How can I modify this query to return distinct Models and VideoProcessor columns ?
SELECT TOP(20) *
FROM
(SELECT
[3D_Benchmarks].Id AS BenchmarkId,
Manufacturer, Model, Slug, VideoProcessor,
FPS, CPU
FROM
[3D_Benchmarks]
JOIN
[3D_Slugs] ON [3D_Benchmarks].Id = [3D_Slugs].BenchmarkId) AS tb
ORDER BY
tb.FPS DESC;
New answer based on your comment. This looks up the twenty highest FPS Model+VideoProcessor. For each of those, it picks the row with the highest FPS.
select details.Model
, details.VideoProcessor
, details.FPS
, <add other columns here>
from (
select top 20 b.Model
, VideoProcessor
from [3D_Benchmarks] b
join [3D_Slugs] s
on b.Id = s.BenchmarkId
group by
b.Model
order by
max(b.FPS) desc
) top20
cross apply
(
select top 1 *
from [3D_Benchmarks[ b
join [3D_Slugs] s
on b.Id = s.BenchmarkId
where b.Model = top20.Model
and b.VideoProcessor = top20.VideoProcessor
order by
b.FPS desc
) details
Related
I have a view created in SQL Server Management Studio that brings in certain data, I need to only select the rows with the minimum sequence. For example, in the screenshot see the job number "50773-4", I would only need to see the row with SEQ number 2. I've tried to Group by Min, but to no avail. Any help would be appreciated.
SELECT
TOP (100) PERCENT dbo.Job_Operation.Job,
MIN(dbo.Job_Operation.Sequence) AS SEQ,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
FROM
dbo.Job_Operation
INNER JOIN dbo.Job ON dbo.Job_Operation.Job = dbo.Job.Job
INNER JOIN dbo.User_Values ON dbo.Job.User_Values = dbo.User_Values.User_Values
INNER JOIN dbo.Work_Center ON dbo.Job_Operation.Work_Center = dbo.Work_Center.Work_Center
GROUP BY
dbo.Job_Operation.Job,
dbo.User_Values.Numeric2,
dbo.Work_Center.UVText4,
dbo.Job.Status,
dbo.Job_Operation.Status,
dbo.User_Values.Decimal1,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
HAVING
(dbo.Work_Center.UVText4 = 'Machining')
ORDER BY
dbo.User_Values.Decimal1 DESC,
SEQ
[enter image description here]
I would try the RANK() window function. Perhaps:
SELECT column1,
column2,
rank() OVER (PARTITION BY job ORDER BY seq) AS seq_by_job
Then use this as a nested statement, and filter on only the min rank (i.e. WHERE nested_statement.seq_by_job = 1)
here is one way :
SELECT
TOP (100) PERCENT Job,
Sequence AS SEQ,
Work_Center,
Department
FROM
( select dbo.Job_Operation.Job,
dbo.Job_Operation.Sequence,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department,
dbo.User_Values.Decimal1 ,
ROW_NUMBER() over (partition by dbo.Job_Operation.Job,
dbo.User_Values.Numeric2,
dbo.Work_Center.UVText4,
dbo.Job.Status,
dbo.Job_Operation.Status,
dbo.User_Values.Decimal1,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
Order by dbo.Job_Operation.Sequence asc) rn
FROM
dbo.Job_Operation
INNER JOIN dbo.Job ON dbo.Job_Operation.Job = dbo.Job.Job
INNER JOIN dbo.User_Values ON dbo.Job.User_Values = dbo.User_Values.User_Values
INNER JOIN dbo.Work_Center ON dbo.Job_Operation.Work_Center = dbo.Work_Center.Work_Center
) tt
WHERE rn = 1
and UVText4 = 'Machining'
You can do:
with
q as (
SELECT
dbo.Job_Operation.Job,
MIN(dbo.Job_Operation.Sequence) AS SEQ,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department,
dbo.User_Values.Decimal1
FROM
dbo.Job_Operation
INNER JOIN dbo.Job ON dbo.Job_Operation.Job = dbo.Job.Job
INNER JOIN dbo.User_Values
ON dbo.Job.User_Values = dbo.User_Values.User_Values
INNER JOIN dbo.Work_Center
ON dbo.Job_Operation.Work_Center = dbo.Work_Center.Work_Center
GROUP BY
dbo.Job_Operation.Job,
dbo.User_Values.Numeric2,
dbo.Work_Center.UVText4,
dbo.Job.Status,
dbo.Job_Operation.Status,
dbo.User_Values.Decimal1,
dbo.Job_Operation.Work_Center,
dbo.Work_Center.Department
HAVING
(dbo.Work_Center.UVText4 = 'Machining')
),
r as (
select *,
row_number() over(partition by job order by seq) as rn
from q
)
select job, seq, work_center, department
from r
where rn = 1
order by Decimal1 DESC
I'm using SQL Server 2014 and I have a problem with a query.
I want to have in my report, ALL the items of the order with ID_Order = 9 that have been delivered. And for the items that have been delivered at two times (Item Code = Art3 for example), I just want to have the last row, that means the last delivery of this Item, with NO repetition.
I already tried these two queries without success:
Attempt #1: DISTINCT
SELECT DISTINCT
Order.ItemCode, Delivery. Qty, Delivery.ID_Delivery,
Order.ID_Order
FROM
Delivery
INNER JOIN
Order ON Order.ID_Order = Delivery.ID_Order
WHERE
Order.ID_Order = '9'
Attempt #2: subquery
SELECT *
FROM
(SELECT
Order.ItemCode, Delivery.Qty,
FROM
Delivery
INNER JOIN
Order ON Order.ID_Order = Delivery.ID_Order
WHERE
Order.ID_Order = '9')
GROUP BY
a.ItemCode, a.Qty
Try this query --
;WITH CTE
AS (
SELECT C.ID_Order
,D.ID_Delivery
,C.ItemCode
,C.Quantity
,ROW_NUMBER() OVER (
PARTITION BY C.ItemCode ORDER BY D.ID_Delivery DESC
) AS RowNum
FROM Customer_Order C
INNER JOIN Delivery D ON C.ID_Order = D.ID_Order
AND C.ItemCode = D.ItemCode
WHERE C.ID_Order = 9
)
SELECT ID_Order
,ID_Delivery
,ItemCode
,Quantity
FROM CTE
WHERE RowNum = 1
SELECT
Order.ItemCode, Delivery. Qty, Delivery.ID_Delivery,
Order.ID_Order
FROM
Delivery
INNER JOIN
Order ON Order.ID_Order = Delivery.ID_Order
WHERE
Order.ID_Order = '9'
AND Delivery.ID_Delivery IN
(
SELECT MAX(ID_Delivery) FROM Delivery D WHERE D.ID_Order = Delivery.ID_Order GROUP BY D.ID_Order
)
I hope it will work for you.
Using SQL Server 2012
I have seen a few threads about this topic but I can't find one that involves multiple joins in the query. I can't create a VIEW on this database so the joins are needed.
The Query
SELECT
p.Price
,s.Type
,s.Symbol
, MAX(d.Date) Maxed
FROM AdventDW.dbo.FactPrices p
INNER JOIN dbo.DimSecurityMaster s
ON s.SecurityID = p.SecurityID
INNER JOIN dbo.DimDateTime d
ON
p.DateTimeKey = d.DateTimeKey
GROUP BY p.Price ,
s.Type ,
s.Symbol
ORDER BY s.Symbol
The query works but does not produce distinct results. I am using Order by to validate the results, but it is not required once I get it working. I The result set looks like this.
Price Type Symbol Maxed
10.57 bfus *bbkd 3/31/1989
10.77 bfus *bbkd 2/28/1990
100.74049 cbus 001397AA6 8/2/2005
100.8161 cbus 001397AA6 7/21/2005
The result set I want is
Price Type Symbol Maxed
10.77 bfus *bbkd 2/28/1990
100.74049 cbus 001397AA6 8/2/2005
Here were a few other StackOverflow threads I tried but couldn't get t work with my specific query
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
SQL Selecting distinct rows from multiple columns based on max value in one column
If you want data for the maximum date, use row_number() rather than group by:
SELECT ts.*
FROM (SELECT p.Price, s.Type, s.Symbol, d.Date,
ROW_NUMBER() OVER (PARTITION BY s.Type, s.Symbol
ORDER BY d.Date DESC
) as seqnum
FROM AdventDW.dbo.FactPrices p INNER JOIN
dbo.DimSecurityMaster s
ON s.SecurityID = p.SecurityID INNER JOIN
dbo.DimDateTime d
ON p.DateTimeKey = d.DateTimeKey
) ts
WHERE seqnum = 1
ORDER BY s.Symbol;
You should use a derived table since you really only want to group the DateTimeKey table to get the MAX date.
SELECT p.Price ,
s.Type ,
s.Symbol ,
tmp.MaxDate
FROM AdventDW.dbo.FactPrices p
INNER JOIN dbo.DimSecurityMaster s ON s.SecurityID = p.SecurityID
INNER JOIN
( SELECT MAX(d.Date) AS MaxDate ,
d.DateTimeKey
FROM dbo.DimDateTime d
GROUP BY d.DateTimeKey ) tmp ON p.DateTimeKey = tmp.DateTimeKey
ORDER BY s.Symbol;
/*
this is your initial select which is fine because this is base from your original criteria,
I cannot ignore this so i'll keep this in-tact. Instead from here i'll create a temp
*/
SELECT
p.Price
, s.Type
, s.Symbol
, MAX(d.Date) Maxed
INTO #tmpT
FROM AdventDW.dbo.FactPrices p
INNER JOIN dbo.DimSecurityMaster s
ON s.SecurityID = p.SecurityID
INNER JOIN dbo.DimDateTime d
ON p.DateTimeKey = d.DateTimeKey
GROUP BY p.Price ,
s.Type ,
s.Symbol
ORDER BY s.Symbol
SELECT innerTable.Price, innerTable.Symbol, innerTable.Type, innerTable.Maxed
FROM (
SELECT
ROW_NUMBER () OVER (PARTITION BY t1.Symbol, t1.Type, t1.Maxed ORDER BY t1.Maxed DESC) as row
, *
FROM #tmpT AS t1
) AS innerTable
WHERE row = 1
DROP TABLE #tmpT
I'm trying to print out the results from the "GermanDB" Database first, while also showing everything from the Boston DB that was not in the German database. Can this be done in one query?
My query (the bold part functions but does not order the way I want)
select * from (
SELECT DISTINCT a.ProductRef
FROM GERMANDB.dbo.LOCATIONS AS a INNER JOIN GERMANDB.dbo.ITEMS AS b ON a.ProductRef = b.ProductRef
WHERE b.ACTIVE=1
) ta
UNION select * from
SELECT DISTINCT c.ProductRef
FROM BOSTONDB.dbo.LOCATIONS AS c INNER JOIN BOSTONDB.dbo.ITEMS AS d ON c.ProductRef = d.ProductRef
WHERE c.ACTIVE=1 (c.ProductRef NOT IN
(SELECT ProductRef FROM GERMANDB.dbo.ITEMS where ACTIVE=1))
) tb
order by ta.ProductRef** , tb.productRef
Just add one field to signal the priority. Like this:
select *, 0 as Priority from (
SELECT DISTINCT a.ProductRef
FROM GERMANDB.dbo.LOCATIONS AS a INNER JOIN GERMANDB.dbo.ITEMS AS b ON a.ProductRef = b.ProductRef
WHERE b.ACTIVE=1
) ta
UNION select *, 1 as Priority from
SELECT DISTINCT c.ProductRef
FROM BOSTONDB.dbo.LOCATIONS AS c INNER JOIN BOSTONDB.dbo.ITEMS AS d ON c.ProductRef = d.ProductRef
WHERE c.ACTIVE=1 (c.ProductRef NOT IN
(SELECT ProductRef FROM GERMANDB.dbo.ITEMS where ACTIVE=1))
) tb
order by Priority, ProductRef
I hope somebody may be able to point out where i'm going wrong here but i've been looking at this for the last 30 minutes and not gotten anywhere with it.
I have a temporary table that is populated with data, the front end application cannot do any logic for me so please excuse the ugly case statement logic in the table.
The user is happy with the resultset brought back as I get the top 10 records. They have now decided they want to see a group of the remaining countries (all rows not in the top 10) as 'Other'.
I have tried to create a grouping of countries not in the top 10 but it's not working, I was planning on UNION'ing this result to the top 10 results.
SELECT c.Country, count(*) AS 'Total_Number_of_customers', COALESCE(ili.new_customers,0) AS 'New_Customers', COALESCE(ilb.existing_first,0) AS 'Existing_First_Trans', COALESCE(ilc.existing_old,0) AS 'Existing_Prev_Trans'
FROM #customer_tmp c
LEFT JOIN (SELECT z.country, count(*) AS 'new_customers' FROM #customer_tmp z where z.customer_type='New_Customer' group by z.country)ili ON ili.country = c.country
LEFT JOIN (SELECT zy.country, count(*) AS 'existing_first' FROM #customer_tmp zy where zy.customer_type='Existing_Customer' AND zy.first_transaction=1 group by zy.country)ilb ON ilb.country = c.country
LEFT JOIN (SELECT zx.country, count(*) AS 'existing_old' FROM #customer_tmp zx where zx.customer_type='Existing_Customer' AND zx.first_transaction=0 group by zx.country)ilc ON ilc.country = c.country
GROUP BY c.country, ili.new_customers, ilb.existing_first, ilc.existing_old
ORDER BY 2 DESC
Here is the SQL that I use to get results from my table.
For reference, each row in my temporary table contains a customer ID, the date they were created and their customer type, which is specific to what i'm trying to achieve.
Hopefully this is a simple problem and i'm just being a bit slow..
Many thanks in Adv.
Use the EXCEPT operator in SQL Server:
SELECT <fields>
FROM <table>
WHERE <conditons>
EXCEPT
<Query you want excluded>
Yup; EXCEPT, or maybe add a row number to your query and then select by that:
SELECT * FROM (
SELECT c.Country, count(*) AS 'Total_Number_of_customers',
row_number() OVER (ORDER BY COUNT(*) DESC) AS 'r',
COALESCE(ili.new_customers,0) AS 'New_Customers', COALESCE(ilb.existing_first,0) AS 'Existing_First_Trans', COALESCE(ilc.existing_old,0) AS 'Existing_Prev_Trans'
FROM #customer_tmp c
LEFT JOIN (SELECT z.country, count(*) AS 'new_customers' FROM #customer_tmp z where z.customer_type='New_Customer' group by z.country)ili ON ili.country = c.country
LEFT JOIN (SELECT zy.country, count(*) AS 'existing_first' FROM #customer_tmp zy where zy.customer_type='Existing_Customer' AND zy.first_transaction=1 group by zy.country)ilb ON ilb.country = c.country
LEFT JOIN (SELECT zx.country, count(*) AS 'existing_old' FROM #customer_tmp zx where zx.customer_type='Existing_Customer' AND zx.first_transaction=0 group by zx.country)ilc ON ilc.country = c.country
GROUP BY c.country, ili.new_customers, ilb.existing_first, ilc.existing_old
ORDER BY 2 DESC
) sub_query WHERE sub_query.r >= 10
This may be more flexible, as you can run one query and then divide the results up into "top ten" and "the rest" quite easily.
(This is equivalent to bobs' answer; I guess we were working on this at exactly the same time!)
Here's an approach using common table expressions (CTE)
WITH CTE AS
(
SELECT c.Country, count(*) AS 'Total_Number_of_customers', COALESCE(ili.new_customers,0) AS 'New_Customers', COALESCE(ilb.existing_first,0) AS 'Existing_First_Trans', COALESCE(ilc.existing_old,0) AS 'Existing_Prev_Trans'
, ROW_NUMBER() OVER (ORDER BY count(*) DESC) AS sequence
FROM #customer_tmp c
LEFT JOIN (SELECT z.country, count(*) AS 'new_customers' FROM #customer_tmp z where z.customer_type='New_Customer' group by z.country)ili ON ili.country = c.country
LEFT JOIN (SELECT zy.country, count(*) AS 'existing_first' FROM #customer_tmp zy where zy.customer_type='Existing_Customer' AND zy.first_transaction=1 group by zy.country)ilb ON ilb.country = c.country
LEFT JOIN (SELECT zx.country, count(*) AS 'existing_old' FROM #customer_tmp zx where zx.customer_type='Existing_Customer' AND zx.first_transaction=0 group by zx.country)ilc ON ilc.country = c.country
GROUP BY c.country, ili.new_customers, ilb.existing_first, ilc.existing_old
)
SELECT *
FROM CTE
WHERE sequence > 10
ORDER BY sequence
SELECT country, COUNT(*) cnt, SUM(new_customer), SUM(existing_first_trans), SUM(existing_prev_trans)
FROM (
SELECT CASE
WHEN country IN
(
SELECT TOP 10 country
FROM #customer_tmp
ORDER BY
COUNT(*) DESC
) THEN
country
ELSE 'Others'
END AS country,
CASE WHEN customer_type = 'New_Customer' THEN 1 END AS new_customer,
CASE WHEN customer_type = 'Existing_Customer' AND first_transaction = 1 THEN 1 AS existing_first_trans,
CASE WHEN customer_type = 'Existing_Customer' AND first_transaction = 0 THEN 1 AS existing_prev_trans,
FROM #customer_tmp
)
GROUP BY
country
ORDER BY
CASE country WHEN 'Others' THEN 2 ELSE 1 END, cnt DESC