I have a table with Display_UPC, Brand, Item_Description, and other fields. There are several items with the same Display_UPC (all items belonging to the same display), and some displays have multiple brands.
I'm trying to print out a page that shows all of the Display contents (all Display_UPC together) with the various item descriptions, but sorted by Brand (so it starts with the "A" brands at the top of the page, then "B" brands, etc...).
Problem is, if I try:
SELECT DISTINCT *
FROM tbl_All_Displays
ORDER BY Brand, Display_UPC
some of the displays (the ones containing multiple brands) are missing some items because they are different brands. I can get rid of "Brand" in the ORDER BY and it returns complete displays together but they are not sorted by Brand (obviously).
I'm guessing maybe a GROUP BY is needed here but I can't get one to work. If I try something like:
SELECT DISTINCT *
FROM tbl_All_Displays
GROUP BY Display_UPC
ORDER BY Brand, Display_UPC
I get the error:
Column 'tbl_All_Displays.Item_Description' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
But I need Item_Description (and the other various fields) to be displayed on the page. They just aren't important in the ordering/grouping.
Sample Data:
Sample Expected Result:
So, basically, it doesn't matter which brand in a display the query uses in the sort. If a display contains a brand then it's okay for it to belong to that brand "group" if that makes sense. Is this possible?
Note: I deleted and reposted a previos question because it got messy with edits.
Edit: Here is sqlfiddle with sample table data - http://sqlfiddle.com/#!6/5069c
You want to sort first by the min(Brand) of each Display_UPC?
Then you need to sort by a "Group Min" first (fiddle:
SELECT *
FROM Table1
ORDER BY
min(Brand) over (partition by Display_UPC),
Display_UPC,
Brand
dnoeth did a great solution. But i want show the one I was working with.
SQL FIDDLE DEMO
with
minBrand as (
SELECT Display_UPC, MIN(BRAND) Brand
from Table1
GROUP BY Display_UPC
)
select m.Brand MainBrand, t.*
from minBrand m
inner join Table1 t
on m.Display_UPC = t.Display_UPC
order by m.Brand, t.Display_UPC, t.Brand, t.Item_Description
Related
I would like to iterate the same query while using different parameter values from a predefined list.
Say, I have a table with two columns. The first columns contains customer name. The second column contains customer spending.
###CUSTOMER; SPENDING###
customer1; 1000
customer2; 111
customer3; 100
customer1; 323
...
I know the complete list of customers: customerlist = {customer1, customer2, customer3}.
I would like to do something like:
Select sum(spending)
from mytable
where customer = #customerlist
The query should compute the sum of spending for each customer defined in the customer list. I have found some examples of sql procedures with stored parameters but not the case with one parameter of multiple values.
Thank you
P.S. This is just a hypothetical example to illustrate my question (I know it would be much more effective to use here a simple group by).
You can use nested query like this
SELECT CustomerList.CustomerName Cust, isnull((SELECT SUM(Spending) CustSpending
FROM Customer
WHERE Customer.CustomerName = CustomerList.CustomerName),0)
FROM CustomerList
This would normally be done using GROUP BY:
Select customer, sum(spending)
from mytable
group by customer;
GROUP BY is a very fundamental part of SQL. You should review your knowledge of SQL so you understand how to use it.
Question: Select the item and per unit price for each item in the items_ordered table. Hint: Divide the price by the quantity.
1.
select item, sum(price)/sum(quantity)
from items_ordered
group by item;
2.
select item, price/quantity
from items_ordered
group by item;
Have a look at the resultis for flashlights. First one shows average price correctly but 2nd one only takes 28/4 and shows 7, ignoring the 4.5 few rows down. Someone please explain why this is the case.
The used table data from an external website.
SUM() is a group function - so that essentially says go get me all the price and quantities by item, and add them all up to return them in one row.
MySQL is quite forgiving when grouping things and will try to retrieve a rowset (which is why your second example returns something - albeit wrong).
Generally, if you are GROUPing columns (items in your exmaple), you need to return one row per column (item).
Try running the SQL below to see what that looks like.
SELECT item
, SUM(price) AS sum_price
, SUM(quantity) AS sum_quantity
, COUNT(*) AS item_count
, SUM(price) / SUM(quantity) AS avg_price_per_quant
FROM items_ordered
GROUP BY item
ORDER BY item ASC
The first query returns the average price for that item, the second query returns the price for the first item it encounters. This only works in MySQL, the second query would error in SQL Server as no aggegrate function is used. See this post for more details Why does MySQL allow "group by" queries WITHOUT aggregate functions?.
I'm currently re-working the size filter i built earlier this year for our website. The size filter query works off the stock_id's found in the products query. On occassions, the same product can appear many times, due to it being a single listing as well as appearing inside a mix and match listing.
Because the stock_id remains the same however, whenever i run a query using stock_id In (#products.stock_id#), i only get the one row, when because lets say products.stock_id equals 1234,1234,1235. 1234 will only be shown once rather than twice, how do i get this record to be counted twice? I know it's not the most straightforward of questions but i don't have much time to dedicate to this post unfortunately.
EDIT 1 - Size Filter Query
<cfquery datasource="#application.datasource#" name="size_filter">
Select size_id,
size_description,
size_count
From sizes
Inner Join (
Select stock_sizeid,
Count(*) As size_count
From stock
Where stock_id In (#valueList(products.stock_id)#)
And stock_sizeid Not In ('33','218')
And stock_instock > 0
Group By stock_sizeid
) As stock
On size_id = stock_sizeid
Order By size_description Asc
</cfquery>
Cheat, and JOIN to your id list (instead of using an IN clause):
<cfquery datasource="#application.datasource#" name="size_filter">
Select size_id,
size_description,
size_count
From sizes
Inner Join (Select stock_sizeid,
Count(*) As size_count
From stock
Join (Select stock_id
From (VALUES(#valueList(products.stock_id)#)) a(stock_id)) As ids
On ids.stock_id = stock.stock_id
Where stock_sizeid Not In ('33','218')
And stock_instock > 0
Group By stock_sizeid) As stock
On size_id = stock_sizeid
Order By size_description Asc
</cfquery>
To make VALUES() give rows instead of columns, the correct form is VALUES(1), (2), ...(n). I'm assuming valueList(...) is some client-side procedure that gets run when the statement gets prepared; you'll need to provide an equivalent function to produce this output.
(Note, I've never used coldfusion, so I don't know if this actually works. This type of thing works in most RDBMSs, although some complain)
What this is doing is turning your list into a virtual table, which has all your entries in it, so the JOIN will be assessed multiple times, as normal.
I'm trying to create a stock list but only showing unique part numbers
The distinct line works and displays only unique part numbers
SELECT distinct PartNumber FROM v_StockValuation
However when I include this in the following way it displays several lines with the same part number
SELECT * FROM v_StockValuation
WHERE partnumber IN
(
SELECT distinct PartNumber FROM v_StockValuation
)
order by PartNumber
I've tried adding
GROUP BY partnumber HAVING COUNT(*) = 1 but this ends up excluding partnumbers which exist more than once
I'm probably missing something simple. Could someone guide me please?
Thanks
You can do:
SELECT * FROM v_StockValuation group by PartNumber;
I want to select the entire first row of each record where a promo code is unique. I am trying to create a samples table, in this table will be one record (the first record) from each distinct promo code. I have asked all of my co-workers and they usually go though the data by hand and select one from each. the problem is that the number of promo codes grows each time and the codes change. so I want to write a query that will select the first record found to have each distinct code. so for I have something like this:
SELECT DISTINCT Customer.promo1 FROM Customer AS promo;
SELECT * FROM Customer, promo
WHERE Customer.promo1 = promo.promo1;
But this obviously give the original table. I do have a ID field called AutoID in Customer.
Thanks in advance.
I'm assuming you want the first Customer.AutoId associated with each Customer.Promo
SELECT
c.*
FROM
Customer c
INNER JOIN
(
SELECT
c.promo1,
MIN(c.AutoID) AutoID
FROM
Customer c
GROUP BY
c.promo1) FirstCusomterWithPromo
ON c.AutoID = FirstCusomterWithPromo.AutoID
Something like that:
SELECT * FROM Customer
GROUP BY Customer.promo1