Query skeleton
SELECT col, SUM(x) AS total
FROM t JOIN u ON t.id=u.id
WHERE row_condition
GROUP BY col
HAVING SUM(x) > 100
ORDER BY total DESC
LIMIT 10;
Remember
WHERE filters rows · HAVING filters groups
COUNT(*) counts rows · COUNT(col) skips NULLs
INNER = matches only · LEFT = keep all left rows
Window: SUM(x) OVER (PARTITION BY g ORDER BY d)
The essentials
df = pd.read_csv("f.csv")
df.head(); df.info()
df["col"] # one column
df[df.amount > 100] # filter
df.groupby("region")["amount"].sum()
df.sort_values("amount", ascending=False)
Clean
df.isna().sum()
df["d"] = pd.to_datetime(df["d"])
df["a"] = df["a"].astype(float)
df.drop_duplicates()
Remember
Combine filters with & | and wrap in ( )
SUM(x) OVER stays row-level; groupby collapses
Chart picker
Compare categories → bar
Trend over time → line
Two numbers → scatter
Distribution → histogram / box
Dense scatter → add alpha / hexbin
Design rules
Title = the takeaway, not the topic
Label directly · drop the legend when you can
Color = meaning, not decoration
Bars start at zero. Always.