Count values from a concatenated column? - sql

I'm running this query, but I'm getting and error when I add count
SELECT
CONCAT (product_code, product_color) AS new_product_code
FROM [dbo].[Furniture]
where product = 'couch'
enter image description here
I would like to add another column and be able to count how many times a product was purchased according to its color. But I want to keep the product_code and product_color concatenated in a column. Any suggestions?
Thanks

I suspect when you added count(), you didn't have the GROUP BY
The traditional approach
Select Prod_Color = CONCAT(product_code, product_color )
,count(*)
From [dbo].[Furniture]
Where product = 'couch'
Group By CONCAT(product_code, product_color )
Or using a CROSS APPLY for a single expression
Select Prod_Color
,count(*)
From [dbo].[Furniture]
Cross Apply ( values ( CONCAT(product_code, product_color ) ) ) V(Prod_Color)
Where product = 'couch'
Group By Prod_Color

Related

Get the difference of unique elements of a flag-based ID in SQL

I have an SQL table from which I want to extract unique elements by ID, comparing different groups, for example :
ID,Group,Product
a,2,33
a,1,83
b,3,51
c,2,33
b,1,20
a,3,20
b,2,51
a,2,83
If I have two products equals in different groups for the same ID, then I don't save them. Resulting this:
ID,Group,Unique
a,2,33
c,2,33
b,1,20
a,3,20
I'm trying this in SQL, but I don't know how to do it, please help me!
Remove all rows that have the same product and different groups:
select *
from yourtable a
where not exists(
select 1 from yourtable b where a.Product = b.Product and a.Group <> b.Group
)
select * from table_1
qualify count("product") over(partition by "group")=1
One method is aggregation:
select id, max(group) as group, product
from t
group by id, product
having min(group) = max(group);

Convert column values to columns

Currently the database looks like below :
I am trying to convert it as below :
The best way I could come up with was a SQL pivot. But that groups the Product ID and gives only one of the three 330 rows that we see above. I am not able to think of any other way to approach this. If anyone could think of any way to solve could you please share your thoughts ?
You can use conditional aggregation:
select productid,
max(case when description = 'Part No' then unitdesc end) as partno,
. . . -- and so on for the other columns
from t
group by productid;
EDIT:
I see, you have multiple rows per product. You have a problem, because SQL tables represent unordered sets. There is no ordering, unless you have a column that specifies the ordering. That is not obvious.
So, the following will create single rows, but not necessarily combined as you would like:
select productid,
max(case when description = 'Part No' then unitdesc end) as partno,
. . . -- and so on for the other columns
from (select t.*, row_number() over (partition by productid, description order by productid) as seqnum
from t
) t
group by productid, seqnum;
If you have a column that does capture the ordering of the rows, then use that column in the order by.
You can use LEFT JOIN to retrieve the corresponding values:
select
p.product_id,
n.unit_desc as part_no,
d.unit_desc as description,
pn.unit_desc as price_now,
u.unit_desc as unit
from (select distinct product_id from t) p
left join (select product_id, description from t where description = 'Part No') n
left join (select product_id, description from t where description = 'Description') d
left join (select product_id, description from t where description = 'Price Now') pn
left join (select product_id, description from t where description = 'Unit') u

SQL Select unique combinations of rows for other column value

I’m trying to do an analysis of the different combinations of taxes per invoice to identify how many scenarios exist.
In the tax table, column 1 is invoiceNo, column 2 is taxType. These form the composite key. There can be 1 or more taxType per invoiceNo. Example of data:
https://i.imgur.com/bcQc7vY_d.jpg?maxwidth=640&shape=thumb&fidelity=medium (Sorry but i’m new so can’t add picture).
I want to be able to report on unique taxType for any invoiceNo. Ie, 1 A is unique comb 1, 2 AB is unique comb 2, 3 A is disregarded as already returned for 1, and 4 BC is unique comb 3.
Not sure if this makes sense! Finding it hard to articulate what I’m after!
Expected output would be:
A
AB
BC
The original version of this question was tagged MySQL, so this answers the question.
If I understand correctly, you can use group_concat():
select distinct group_concat(taxtype order by taxtype)
from t
group by invoiceno;
This works with the table you have given and would work with those combinations of Tax types even if they repeat but if there are more tax codes, or there is an AC combination, or if some of the given combinations are omitted then it might get little different! You could develop this to suit the conditions, or you could give some more info: Do invoices have three codes (ABC)? do invoices have just B or just C codes? I notice that the BC invoice etc
WITH CTE (RN,InvoiceNo,TT1,TT2)
AS
(
SELECT ROW_NUMBER() OVER (ORDER BY a.InvoiceNo),a.InvoiceNo,a.TaxType,b.TaxType
FROM UniqueCombo a INNER JOIN UniqueCombo b ON a.InvoiceNo=b.InvoiceNo
)
,
CTE2 (RN,InvoiceNo,TT1,TT2)
AS
(
SELECT * FROM CTE WHERE RN IN
(
SELECT MAX(RN) FROM CTE WHERE TT1=TT2 GROUP BY InvoiceNo HAVING COUNT(InvoiceNo)=1
)
)
SELECT TT1 FROM CTE2 WHERE RN IN
(
SELECT MAX(RN) FROM CTE WHERE TT1=TT2 GROUP BY TT1,TT2 HAVING COUNT(InvoiceNo)>1
)
UNION
SELECT TT1+''+TT2 FROM CTE WHERE RN IN
(
SELECT MAX(RN)-1 FROM CTE WHERE TT1<>TT2 GROUP BY InvoiceNo
)
You can try STRING_AGG. Something like:
SELECT DISTINCT TaxTypeString
FROM
(
SELECT InvoiceNo, STRING_AGG(TaxType, '') AS TaxTypeString
FROM t
GROUP BY InvoiceNo
) x
ORDER BY TaxTypeString
The nested query, called x, should give you one row per invoice number, in the format you want. Then you have to select the distinct tax types from there.

SQL: Take 1 value per grouping

I have a very simplified table / view like below to illustrate the issue:
The stock column represents the current stock quantity of the style at the retailer. The reason the stock column is included is to avoid joins for reporting. (the table is created for reporting only)
I want to query the table to get what is currently in stock, grouped by stylenumber (across retailers). Like:
select stylenumber,sum(sold) as sold,Max(stock) as stockcount
from MGTest
I Expect to get Stylenumber, Total Sold, Most Recent Stock Total:
A, 6, 15
B, 1, 6
But using ...Max(Stock) I get 10, and with (Sum) I get 25....
I have tried with over(partition.....) also without any luck...
How do I solve this?
I would answer this using window functions:
SELECT Stylenumber, Date, TotalStock
FROM (SELECT M.Stylenumber, M.Date, SUM(M.Stock) as TotalStock,
ROW_NUMBER() OVER (PARTITION BY M.Stylenumber ORDER BY M.Date DESC) as seqnum
FROM MGTest M
GROUP BY M.Stylenumber, M.Date
) m
WHERE seqnum = 1;
The query is a bit tricky since you want a cumulative total of the Sold column, but only the total of the Stock column for the most recent date. I didn't actually try running this, but something like the query below should work. However, because of the shape of your schema this isn't the most performant query in the world since it is scanning your table multiple times to join all of the data together:
SELECT MDate.Stylenumber, MDate.TotalSold, MStock.TotalStock
FROM (SELECT M.Stylenumber, MAX(M.Date) MostRecentDate, SUM(M.Sold) TotalSold
FROM [MGTest] M
GROUP BY M.Stylenumber) MDate
INNER JOIN (SELECT M.Stylenumber, M.Date, SUM(M.Stock) TotalStock
FROM [MGTest] M
GROUP BY M.Stylenumber, M.Date) MStock ON MDate.Stylenumber = MStock.Stylenumber AND MDate.MostRecentDate = MStock.Date
You can do something like this
SELECT B.Stylenumber,SUM(B.Sold),SUM(B.Stock) FROM
(SELECT Stylenumber AS 'Stylenumber',SUM(Sold) AS 'Sold',MAX(Stock) AS 'Stock'
FROM MGTest A
GROUP BY RetailerId,Stylenumber) B
GROUP BY B.Stylenumber
if you don't want to use joins
My solution, like that of Gordon Linoff, will use the window functions. But in my case, everything will turn around the RANK window function.
SELECT stylenumber, sold, SUM(stock) totalstock
FROM (
SELECT
stylenumber,
SUM(sold) OVER(PARTITION BY stylenumber) sold,
RANK() OVER(PARTITION BY stylenumber ORDER BY [Date] DESC) r,
stock
FROM MGTest
) T
WHERE r = 1
GROUP BY stylenumber, sold

Query to See Count of ProductName against same ProductId

How to write Sql Query to show Number of Names based on one Product Id.
For example in this example: For ProductId - 263, Count(Name) = 3
I would like to see
263 3
264 2
265 10
266 0 (if null)
SELECT productid, COUNT(*)
FROM products
GROUP BY productid
It's not an exact answer, but it will return the number of occurrences of the productid for each unique productid. It may help you find your result.
Assuming you have a table of products, then you want a left join:
select p.productid, count(pn.productid)
from products p left join
productnames pn
on p.productid = pn.productid
group by p.productid;
Pang.
I have written an answer using a CTE that will give you the count of all the names for each product that can easily be changed to COUNT the DISTINCT names.
;WITH CTE_DISTINCT_NAMES
AS (SELECT --DISTINCT
/* Uncomment "DISTINCT" above
to include duplicate names
in the COUNT
*/
ProductId
, Name
FROM TABLE1
)
SELECT T.ProductId
, COUNT(ISNULL(T.Name,'')) AS [COUNT(Name)]
FROM CTE_DISTINCT_NAMES AS T
GROUP BY T.ProductId
Try this solution:
SELECT
PRODUCT_ID AS PID,
COALESCE(COUNT(NAME), 0) AS CNT
FROM YOUR_TABLE
GROUP BY PRODUCT_ID