I've got few tables like this:
Color
id Color_Name
--- -------
1 RED
2 GREEN
Color_Shades
id ColorId ShadeId date_created
--- ------- ------- --------------
1 1 55 03/15/2013
2 1 43 02/01/2012
3 2 13 05/15/2011
4 2 15 06/11/2009
I'm trying to get a list of all distinct colors with their latest date.
I tried
SELECT a.Color_Name, b.date_created FROM Color a, Color_Shades b
WHERE a.id = b.ColorId
but this is giving me mixed results.
My desired results are:
Color_Name date_created
---------- ---------------
RED 03/15/2013
GREEN 05/15/2011
You are near to what you need. You just need to aggregate those columns using MAX to get theor latest date.
SELECT a.Color_name, MAX(b.date_created) date_created
FROM Color a
INNER JOIN Color_shades b
ON a.id = b.colorID
GROUP BY a.Color_Name
SQLFiddle Demo
Related
If there is a table called variant
id slug slug_id
------- --------- ----------
1 s 10
1 m 10
1 l 10
1 black 11
1 pink 11
1 ship_us 12
1 ship_uk 12
2 xl 10
2 xxl 10
2 blue 11
2 white 11
Result I need in this format:
id variant_slug
-------- ------------
1 1-s-black-ship_us
1 1-s-black-ship_uk
1 1-s-pink-ship_us
1 1-s-pink-ship_uk
1 1-m-black-ship_us
1 1-m-black-ship_uk
1 1-m-pink-ship_us
1 1-m-pink-ship_uk
1 1-l-black-ship_us
1 1-l-black-ship_uk
1 1-l-pink-ship_us
1 1-l-pink-ship_uk
2 2-xl-blue
2 2-xl-white
2 2-xxl-blue
2 2-xxl-white
Q: this record is in same variant table. I have almost no experience using UDFs, stored procedures, I need to be done this thing through query. Is this possible without using UDFs, SP's.
Perhaps a self-join assuming the length of size<=3.
Select A.ID
,variant_slug = concat(A.id,'-',A.slug,'-',B.slug)
from YourTable A
Join YourTable B
on A.ID=B.ID
and A.slug<>B.slug
and len(B.slug)>3
and len(A.slug)<=3
Results
ID variant_slug
1 1-l-black
1 1-l-pink
1 1-m-black
1 1-m-pink
1 1-s-black
1 1-s-pink
2 2-xl-blue
2 2-xl-white
2 2-xxl-blue
2 2-xxl-white
Rather than len(), you can enumerate the sizes i.e. {NOT } IN ('s','m','l','xl','xxl')
Select A.ID
,variant_slug = concat(A.id,'-',A.slug,'-',B.slug)
from YourTable A
Join YourTable B
on A.ID=B.ID
and A.slug<>B.slug
and B.slug NOT IN ('s','m','l','xl','xxl')
and A.slug IN ('s','m','l','xl','xxl')
You can go for INNER JOIN by separating the table into two separate tables: size, color and get the variant data, as given below:
declare #slug table(id int, slug varchar(100))
insert into #slug values
(1,'s')
,(1,'m')
,(1,'l')
,(1,'black')
,(1,'pink')
,(2,'xl')
,(2,'xxl')
,(2,'blue')
,(2,'white');
SELECT size.id, CONCAT_WS('-',size.id,size.size, color.color) as variant_size
from (select id,slug as size from #slug where slug in ('s','m','l','xl','xxl') ) as size
INNER JOIN (select id,slug as color from #slug where slug NOT in ('s','m','l','xl','xxl') ) as COLOR
on color.id = size.id
id
variant_size
1
1-s-black
1
1-s-pink
1
1-m-black
1
1-m-pink
1
1-l-black
1
1-l-pink
2
2-xl-blue
2
2-xl-white
2
2-xxl-blue
2
2-xxl-white
I've been browsing this site for quite a while and this is my first post so I hope I've learned the correct way how to inquire... I've been stuck on this problem for quite a while even with all the available information I'm still lost.
I have 3 tables.
Sets, UserBudget, ItemCosts
table name column names
----------- ------------------------
Sets SetID
UserBudget UserID | ItemID | ItemBudget
ItemCosts SetID | ItemID | ItemPrice
ItemCosts contains multiple items, that are connected to a 'Sets' table entry.
I need a way to return the SetID's from the first table only if the UserBudget has all the same items as ItemCosts and all the ItemPrice is equal or lower to ItemBudget.
For example:
Sets ItemCosts UserBudget
----------- ---------- ----------
SetID 1 SetID 1 UserID 1
ItemID 1 2 ItemID 1 2
ItemPrice 10 12 ItemBudget 11 11
This is not supposed to return anything since the second item's price is higher than the user's budget for it.
Sets ItemCosts UserBudget
----------- ---------- ----------
SetID 1 SetID 1 UserID 1
ItemID 1 2 ItemID 1 2
ItemPrice 10 12 ItemBudget 11 12
This is supposed to return Set 1.
Any of my attempts just end up returning the set if one of the items matches the budget.
Here's my current SQL (it's a super simplified version in the end as all my complicated attempts took longer to execute but returned the same result):
SELECT *
FROM UserBudget a
INNER JOIN ItemCosts b on a.ItemID=b.ItemID
INNER JOIN Sets c on b.SetID=c.SetID
WHERE a.UserID=1 AND a.ItemBudget>=b.ItemPrice
You can try next solution:
SELECT a.UserID, GROUP_CONCAT(DISTINCT b.SetID) SetIDs
FROM UserBudget a
LEFT JOIN ItemCosts b on a.ItemID=b.ItemID AND a.ItemBudget>=b.ItemPrice
LEFT JOIN Sets c on b.SetID=c.SetID
WHERE a.UserID=1
GROUP BY a.UserID
HAVING COUNT(a.UserID) = COUNT(b.SetID)
;
MariaDB fiddle
I want to join my first sql query with table Types showed below by id_pr value.ID_PR values are repeated. I want to show all values from ident_st column concatenated with comma separator for same id_pr and rodz_st values. For example: Show all ident_st values for rodz_st='DZE' and id_pr=13.
first query:
SELECT NAME, NO FROM ORDERS o
LEFT JOIN TYPES t ON t.ID_ZM = o.ID_PR
table Orders:
ID ID_ZM NAME NO
---------- ---------- ------- --------
1 12 Dee 333
2 13 Rods 111
table Types:
ID ID_PR RODZ_ST IDENT_ST
---------- ---------- ------- --------
16 12 JEW 646101_1
10 12 JEW 236496_2
11 13 JEW 147301_5
15 13 DZE 259435_1
12 13 OBR 452171_3
13 13 OBR 286432_6
17 12 DZE 618054_1
19 13 DZE 182235_4
I want result like below:
NAME NO JEW DZE OBR
------- ----- ---------------- ------------------ -----------------
Dee 333 646101_1, 236496_2 618054_1
Rods 111 147301_5 259435_1, 182235_4 452171_3, 286432_6
Question: How to create sql join with concatenated statement to get showed result?
You may use list LISTAGG function with DECODE :
SELECT NAME, NO,
LISTAGG(DECODE(RODZ_ST,'JEW',IDENT_ST,NULL), ',') WITHIN GROUP (ORDER BY t.ID DESC, RODZ_ST) AS JEWS,
LISTAGG(DECODE(RODZ_ST,'DZE',IDENT_ST,NULL), ',') WITHIN GROUP (ORDER BY t.ID , RODZ_ST) AS DZE,
LISTAGG(DECODE(RODZ_ST,'OBR',IDENT_ST,NULL), ',') WITHIN GROUP (ORDER BY t.ID , RODZ_ST) AS OBR
FROM ORDERS o
LEFT JOIN TYPES t ON t.ID_PR = o.ID_ZM
GROUP BY NAME, NO;
SQL Fiddle Demo
I have rephrased a previous question MS Access 2010 SQL Top N query by group performance issue (continued) as I believe the context was not clearly described before. The anwwer to my previous question did not provide the top n by group result. The rephrased question is more generic. I have now all data in one table.
Here is my situation: I have a table (Analysis) that contains products (Partnumber) of various categories (Category). Every product has a price (Value). The objective of the query is to show the 10 products with the highest price of each category The table contains 15000 records and will continue to grow.
This is the query:
SELECT
a.Location,
a.Category,
a.Partnumber
a.Value
FROM Analysis a
WHERE a.Partnumber IN (
SELECT TOP 10 aa.Partnumber
FROM Analysis aa
WHERE aa.Category = a.Category
ORDER BY aa.Value DESC
)
ORDER BY
a.Category;
Here is my question: My current query works with 1000 records in the table (respond time 3 seconds). With 15000 records the query runs endlessly long. How can I rebuild the query to significantly improve performance?
The answer to my previous question was to not use the in-list operation. But this eliminated function to give the top n records by group. The query gave the top n of all records.
For sample data in a table called [Analysis]
ID Location Category Partnumber Value
-- --------- -------- ---------- -----
1 here cat1 part001 1
2 there cat1 part002 2
3 wherever cat1 part003 3
4 someplace cat2 part004 4
5 nowhere cat2 part005 5
6 unknown cat2 part006 6
the "ranking query"
SELECT
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value,
COUNT(*) AS CategoryRank
FROM
Analysis a1
INNER JOIN
Analysis a2
ON a1.Category = a2.Category
AND a1.Value <= a2.Value
GROUP BY
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value
returns
ID Location Category Partnumber Value CategoryRank
-- --------- -------- ---------- ----- ------------
1 here cat1 part001 1 3
2 there cat1 part002 2 2
3 wherever cat1 part003 3 1
4 someplace cat2 part004 4 3
5 nowhere cat2 part005 5 2
6 unknown cat2 part006 6 1
so if you only want the top 2 items in each category just wrap the above query in a SELECT ... WHERE
SELECT *
FROM
(
SELECT
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value,
COUNT(*) AS CategoryRank
FROM
Analysis a1
INNER JOIN
Analysis a2
ON a1.Category = a2.Category
AND a1.Value <= a2.Value
GROUP BY
a1.ID,
a1.Location,
a1.Category,
a1.Partnumber,
a1.Value
) AS RankingQuery
WHERE CategoryRank <= 2
ORDER BY Category, CategoryRank
to give you
ID Location Category Partnumber Value CategoryRank
-- -------- -------- ---------- ----- ------------
3 wherever cat1 part003 3 1
2 there cat1 part002 2 2
6 unknown cat2 part006 6 1
5 nowhere cat2 part005 5 2
Note: Ensure that the [Category] and [Value] fields are indexed for best performance.
I'm trying to write a query that will display the minimum value (lowest score) for each hole eliminating any duplicates. In other words, if the minimum score is 3 on hole_num 1 and there are two or more scores with 3, none of the rows corresponding to hole_num 1 should be returned. However, if there is only one value of 3 on hole_num 1 and it is the minimum value, the row should be returned. Here is what I was able to come up with... unfortunately I can't figure out how to remove the duplicates.
sample table:
player_id hole_num score
------------- ------------ -----
1 1 4
1 2 5
2 1 3
2 2 5
my query that gets the minimum score for each hole_num (but does not eliminate the row if it occurs more than once):
select. r.player_id, r.hole_num, r.score
from scorecard_test r
join (select hole_num,
min(score) best
from scorecard_test
group by hole_num) v on r.hole_num = v.hole_num
and r.score = v.best
produces the following output:
player_id hole_num score
---------- --------- -----
1 2 5
2 1 3
2 2 5
I'm trying to write a query that would only display the second row above (score=3) since 5 on hole_num 2 (although it is minimum) is a repeat. Any help would be greatly appreciated.
A MySQL specific solution is to add a GROUP BY and HAVING COUNT(*) = 1 to your current query:
SELECT r.player_id, r.hole_num, r.score
FROM scorecard_test r
JOIN
(
SELECT hole_num, MIN(score) best
FROM scorecard_test
GROUP BY hole_num
) v
ON r.hole_num = v.hole_num AND r.score = v.best
GROUP BY hole_num, score
HAVING COUNT(*) = 1
A solution that would work more generally is to add one more join to find the unique rows:
SELECT r1.player_id, r1.hole_num, r1.score
FROM scorecard_test r1
JOIN
(
SELECT hole_num, MIN(score) best
FROM scorecard_test
GROUP BY hole_num
) v
ON r1.hole_num = v.hole_num AND r1.score = v.best
LEFT JOIN scorecard_test r2
ON r1.hole_num = r2.hole_num AND r1.player_id != r2.player_id AND r1.score = r2.score
WHERE r2.player_id IS NULL
The result in both cases is this:
player_id hole_num score
---------- --------- -----
2 1 3
You might be looking for this: http://www.w3schools.com/sql/sql_distinct.asp
Doing SELECT DISTINCT ... should return a single row for all that are complete duplicates.