Count distinct group by SQL code? - sql

say I had just 2 columns of data....
Postcode Sold date
LE14 6QR 01/01/2011
How could I say...display for each postcode the date for each time a house in that area has been sold.
E.G If that postcode occurs 14 times, it would list each of the dates?
Thanks,

From you description it sounds like you want to list the contents of the table, so you can do:
select Postcode, [Sold date]
from MyTable
If you do not want duplicate dates, you can do:
select Postcode, [Sold date]
from MyTable
group by Postcode, [Sold date]

If you're going to group then you should also COUNT just to make sure you're totals are adding up.
SELECT PostCode, [Sold Date], COUNT(PostCode)
FROM [table]
GROUP BY PostCode, [Sold Date]
ORDER BY COUNT(PostCode) DESC

I think this is what you want:
SELECT PostCode, SoldDate
FROM YourTable
Group By PostCode

Related

BigQuery: Returning Records for a list of specific customers

I have a list of CustomerId in an Excel sheet that I want to use as a filter in BigQuery.
For example:
SELECT CustomerId, Status, OrderTotal, StoreCode, PaymentAmount FROM Orders
WHERE OrderPlacedTime > '2022-01-01'
AND CustomerId = '1,2,3 ... 1000'
Is there an easier way to input all these CustomerId values? Or do I need to transpose the IDs and separate them with a comma in order for the query to run?
Use below as a direction
SELECT CustomerId, Status, OrderTotal, StoreCode, PaymentAmount
FROM Orders
WHERE OrderPlacedTime > '2022-01-01'
AND '' || CustomerId IN UNNEST(SPLIT('1,2,3 ... 1000'))

How to calculate AVG into left join between 2 tables?

I have to calculate the avg of gross revenue on bigquery (the key is item_id).
SELECT
t0.order_create_date AS day,
t0.site_country AS country,
p0.product_brand AS brand,
p0.product_gender AS gender,
p0.product_department AS department,
t0.item_qty AS items_sold,
t0.item_sale_price AS gross_revenue,
t0.item_net_price AS net_revenue,
FROM
`transactions` t0
LEFT JOIN
`products` p0
ON
t0.item_id = p0.item_id
ORDER BY
country,
day ASC
I tried this :
SELECT
t0.order_create_date AS day,
t0.site_country AS country,
p0.product_brand AS brand,
p0.product_gender AS gender,
p0.product_department AS department,
t0.item_qty AS items_sold,
t0.item_sale_price AS gross_revenue,
AVG(t0.item_sale_price) AS average_value,
t0.item_net_price AS net_revenue,
FROM
`transactions` t0
LEFT JOIN
`products` p0
ON
t0.item_id = p0.item_id
ORDER BY
country,
day ASC
Biquery result:
SELECT list expression references t0.order_create_date which is neither grouped nor aggregated at [2:3]
The problem is that you didn't aggregate or by all the other columns, except the average_value one. Here you can read more about Group By.
From the names of the columns you are creating, I suppose you also want to have other information such as gross and net revenue. You would have to use some aggregate function on them too, otherwise the error would continue.
Something like the following should probably work:
SELECT
t0.order_create_date AS day,
t0.site_country AS country,
p0.product_brand AS brand,
p0.product_gender AS gender,
p0.product_department AS department,
sum(t0.item_qty) AS items_sold,
sum(t0.item_sale_price) AS gross_revenue,
AVG(t0.item_sale_price) AS average_value,
sum(t0.item_net_price) AS net_revenue,
FROM
transactions t0
LEFT JOIN
products p0
ON
t0.item_id = p0.item_id
GROUP BY
day,
country,
brand,
gender,
department
ORDER BY
country,
day ASC

In SQL how do I select the latest date that does not have a zero value in another column

I am trying to select the max date in a table that has a Booking Date and a Written Premium value for that date. I want the newest date that has Written Premium (not equal to Zero).
In the above table I want, or expect the 4th Row in my query (7/28/2021, 330000), but I get the first row
(8/20/21, 0)
This is the query I run:
SELECT
MAX(booking_date) AS [Max Booking Date]
FROM
DW.dbo.Table1
GROUP BY
booking_year
HAVING
SUM(written_premium) <> 0
AND booking_year = '2021'
I think this is summing all the written premium, not over the rows so I am just getting the max booking date. Maybe I need a PARTITION BY function or something? I am stuck on this and would appreciate any help on how to best do this.
Thanks,
Brian
I think there are multiple options, but one could be:
SELECT TOP 1 booking_date, written_premium
FROM DW.dbo.Table1
WHERE written_premium <> 0
ORDER BY booking_date DESC
If all you want is the date then there is no need of group by and a HAVING clause.
Set your conditions in the WHERE clause:
SELECT MAX(booking_date) AS [Max Booking Date]
FROM DW.dbo.Table1
WHERE booking_year = '2021' AND written_premium <> 0;
If you want both columns:
SELECT TOP 1 booking_date AS [Max Booking Date], written_premium
FROM DW.dbo.Table1
WHERE booking_year = '2021' AND written_premium <> 0
ORDER BY booking_date DESC;

Analysis of customer along time

I have the task of developing a SQL query for analysing the behaviour of a customer through time.
So, I started with two tables; a calendar table (with each year-month-day of some years), and a sales table (with an ID and a purchase date of my interest) This is the query:
SELECT [Spice Id], FORMAT([Fecha venta],'yyyyMM') AS Purchase_Date
INTO #Sale_date
FROM SALES
WHERE [Spice Id] IS NOT NULL
GROUP BY [Spice Id], [Fecha venta]
enter image description here and enter image description here
Then I use a cross join to have all dates available even though the customer has no purchase in dates, I use a where clause to limit the table as I want to. Query below
SELECT [Spice Id], year, YearMonth, Purchase_Date, (Purchase_Date) AS First_purchase, (Purchase_Date) AS Last_purchase
INTO #Sorted
FROM #calendar
CROSS JOIN #Sale_date
WHERE year > 2019
AND Purchase_Date > 202001
AND Purchase_Date < FORMAT(GETDATE(),'yyyyMM')
AND YearMonth BETWEEN purchase_date AND FORMAT(GETDATE(), 'yyyyMM')
GROUP BY
[Spice Id], Year, YearMonth, Purchase_Date
ORDER BY
[Spice Id], Year ASC, YearMonth, Purchase_date
enter image description here
Then as you can see first purchase and lastpurchase are just the same as purchase date, so I update both values with the following:
----------UPDATE MIN
UPDATE #Sorted
enter code here`SET #SORTED.First_purchase = t1.minimo
FROM #Sorted
INNER JOIN
(SELECT [SPICE ID],MIN([First_purchase]) AS minimo
FROM #Sorted
GROUP BY [Spice Id])
AS t1 on t1.[spice id] = #Sorted.[spice id]
--------------Update Max
UPDATE #Sorted
SET #SORTED.Last_purchase = t1.maximo
FROM #SORTED
INNER JOIN
(SELECT [SPICE ID],MAX([Last_purchase]) AS maximo
FROM #Sorted
where Purchase_Date <= YearMonth
GROUP BY [Spice Id])
AS t1 on t1.[spice id] = #Sorted.[spice id]
So once I updated both values I got the following result, I'll use a specific ID to be more clear:
enter image description here
AS you can see, I have some mistakes Purchase_Date is not correctly ordered, I really don't mind that much because i can drop that column and leave just Start and Last, my big trouble is with last purchase, it should change overtime and update as in the following example I don't know if you find any mistakes in my logic or a better way to get to it, I wish to see the final table as this
enter image description here
I hope it is clear enough, thank you very much for your help!!
I'm not entirely sure your desired output but the updating logic to get the first and last purchase date is entirely unneccessary. You can use something like the below to always obtain these values
min(Purchase_date) over (partition by spice_id) as first_purchase
max(Purchase_date) over (partition by spice_id) as last_purchase
If you wish for purchase date to be ordered correctly then you need to evalute your order by clause, since this is last in the clause it is ordered after the first several columns have been ordered

Equation needing to be in a group by statement?

I have been getting this error:
Column 'dbo.MainDB.Packaging Quantity' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
This problem came up after I added the equation for Total and I have attempted to add aggregate functions to the equation, but it just gives me the wrong output if I add any. Also, if I add it to the group by clause then it adds unnecessary groups, does anyone know a solution?
Code:
SELECT
CONVERT(varchar,shipdate,101) AS Shipdate,
ID,
[Last Name],
Address,
SUM([Packaging Quantity]) AS Quantity,
Size,
SUM(Cost) AS Price,
ROUND(Size/[Packaging Quantity], 0) AS Total
FROM dbo.MainDB
WHERE
Shipdate BETWEEN '09/01/2019' AND '09/30/2019 11:59:59PM'
AND Cost <> '0'
GROUP BY
CONVERT(VARCHAR, shipdate, 101),
ID,
[First Name],
Address,
Size
The error message is clear enough.
SELECT
CONVERT(varchar,shipdate,101) AS Shipdate,
ID,
[Last Name],
Address,
SUM([Packaging Quantity]) AS Quantity, -- aggregation on [Packaging Quantity]
Size,
SUM(Cost) AS Price,
ROUND(Size/[Packaging Quantity], 0) AS Total -- no aggregation on [Packaging Quantity]
FROM ...
You need an aggregate function in the second hilighted occurence of [Packaging Quantity].Given the fact that you are SUMing the first time, it would assume that you want to aggregate the same way in the other column, so:
SELECT
CONVERT(varchar,shipdate,101) AS Shipdate,
ID,
[Last Name],
Address,
SUM([Packaging Quantity]) AS Quantity,
Size,
SUM(Cost) AS Price,
ROUND(Size/SUM([Packaging Quantity]), 0) AS Total
FROM ...