Related
I have made a little example data that I modify in three steps. I cant do it in one, maybe there is a clever way with some logic? I use Microsoft SQL Server
This code will generate the four base tables with example data and the step by step queries I want to combine, the result at the end should have 8 entries:
Reference table:
CREATE TABLE ref
(
ID int NOT NULL
NR int NOT NULL
CONSTRAINT KEYS PRIMARY KEY (ID, NR)
);
INSERT INTO ref
VALUES (1234, 223), (1234, 224), (1234, 225),
(1235, 123), (1235, 124), (1236, 540),
(1236, 541), (1237, 233), (1237, 234);
Con1 table:
CREATE TABLE con1
(
NR int NOT NULL
flag int NOT NULL
PRIMARY KEY (NR)
);
INSERT INTO con1
VALUES (123, 0), (124, 1), (125, 0),
(220, 0), (222, 0), (223, 0),
(224, 0), (225, 1), (300, 0),
(540, 1), (541, 1);
Con2 table:
CREATE TABLE con2
(
NR int NOT NULL
ID int NOT NULL
PRIMARY KEY (NR)
);
INSERT INTO con2
VALUES (123, 1235), (124, 1235), (125, 1243),
(220, 1296), (222, 1255), (223, 1234),
(224, 1234), (225, 1234), (300, 1267),
(540, 1236);
Info table:
CREATE TABLE info
(
NR int NOT NULL
SNR int NOT NULL
SSNR int NOT NULL
Level int not NULL
CONSTRAINT KEYS PRIMARY KEY (NR, SNR, SSNR)
);
INSERT INTO info
VALUES (123, 1, 1, 1), (123, 1, 2, 2),
(123, 1, 3, 2), (123, 2, 1, 1),
(123, 2, 2, 2), (123, 2, 3, 2),
(124, 1, 1, 1), (124, 1, 2, 2),
(124, 1, 3, 2), (125, 1, 1, 1),
(125, 1, 2, 2), (125, 1, 3, 2),
(125, 1, 4, 3), (125, 1, 5, 3),
(220, 1, 1, 1), (220, 1, 2, 2),
(223, 1, 1, 1), (223, 1, 2, 2),
(224, 1, 1, 1), (224, 1, 2, 2),
(224, 1, 3, 2), (225, 1, 1, 1),
(225, 1, 2, 2), (300, 1, 1, 1),
(300, 1, 2, 2), (300, 2, 1, 1),
(300, 2, 2, 2), (540, 1, 1, 1),
(541, 1, 1, 1);
Step #1:
SELECT *
FROM con1
INNER JOIN con2 ON con1.NR = con2.NR
WHERE con1.flag = 1
Step #2:
SELECT ref.*
FROM ref
INNER JOIN step1 ON ref.ID = step1.ID
Step #3:
SELECT *
FROM step2
INNER JOIN info ON step2.NR = info.NR
WHERE info.Level = 1
I tried some different ways but always get too much resulting rows
the result should look like this:
ID
NR
Level
SNR
SSNR
1234
223
1
1
1
1234
224
1
1
1
1234
225
1
1
1
1235
123
1
1
1
1235
123
1
2
1
1235
124
1
1
1
1236
540
1
1
1
1236
541
1
1
1
It should be all entries from info with Level=1
excluding:
all NR that do not occur in the intersection of con1 and con2
all NR that con1 lists with flag = 0
but including:
all excluded NR that run with the same ID (according to ref) as any NR not excluded prior
the result has the same columns as info with on NR matching IDs from ref
You can do this easily with Common Table Expressions:
with step1 As (
Select *
From con1
Inner Join con2 On con1.NR = con2.NR
Where con1.flag = 1
), step2 As (
Select ref.*
From ref
Inner Join step1 On ref.ID = step1.ID
)
Select *
From step2
Inner Join info On step2.NR = info.NR
Where info.Level = 1
First, I apologize if the title won't make sense but below is the detailed scenario.
Say I have a document_revision table
id document_id phase_id user_id
1 1 3 1
2 1 2 1
3 1 1 1
4 2 3 2
5 2 2 2
where phase_id is: transcribe = 3; proof = 2; and submit = 1.
I would like to write a query where I can filter the revision records where I will disregard a proof phase if the same user did the transcribe and proof. So the output would be:
id document_id phase_id user_id
1 1 3 1
3 1 1 1
4 2 3 2
I've been struggling for hours figuring out a query for this but no luck so far.
Assuming you only want the phase 3 for any case where a user_id was involved in phase 2 and 3, then one way you could do this is with ROW_NUMBER(), e.g.:
DECLARE #T TABLE (ID INT IDENTITY(1, 1), Document_ID INT, Phase_ID INT, [User_ID] INT);
INSERT #T (Document_ID, Phase_ID, [User_ID]) VALUES
(1, 1, 1), (1, 2, 1), (1, 3, 1), (2, 3, 2), (2, 2, 2), (3, 1, 1), (3, 2, 1), (3, 3, 2);
SELECT ID, Document_ID, Phase_ID, [User_ID]
FROM
(
SELECT *, RN = ROW_NUMBER() OVER (PARTITION BY Document_ID, [User_ID], CASE WHEN Phase_ID IN (2, 3) THEN 2 ELSE Phase_ID END ORDER BY Phase_ID DESC)
FROM #T
) AS T
WHERE RN = 1;
DECLARE #document_revision TABLE (
id INT IDENTITY(1,1),
document_id INT,
phase_id INT,
user_id INT
);
INSERT INTO #document_revision
(document_id, phase_id, user_id)
VALUES
(1, 3, 1),
(1, 2, 1),
(1, 1, 1),
(2, 3, 2),
(2, 2, 2),
-- To test a scenario where there is a proof and a submit with no transcribe phases and same document
(3, 2, 3),
(3, 1, 3),
-- To test a scenario where there is a transcribe and a submit with no proof phases and same document
(4, 3, 4),
(4, 1, 4),
-- To test a scenario where there is a proof and a submit with no transcribe phase (for document_id 5) but different document and same user as above
(5, 2, 4);
SELECT dr.id
, dr.document_id
, dr.phase_id
, dr.user_id
FROM #document_revision AS dr
WHERE NOT EXISTS ( SELECT 1
FROM #document_revision AS temp
-- Same user
WHERE temp.user_id = dr.user_id
-- Same document
AND temp.document_id = dr.document_id
-- To check if there is already a transcribe phase_id with the same user_id and document_id
AND temp.phase_id = 3
-- -- To check if there is already a proof phase_id with the same user_id and document_id
AND dr.phase_id = 2 )
results:
id document_id phase_id user_id
1 1 3 1
3 1 1 1
4 2 3 2
6 3 2 3
7 3 1 3
8 4 3 4
9 4 1 4
10 5 2 4
Select query is not working when use variable in MSSQL2014
My Schema is :-
CREATE TABLE product
(idproduct int, name varchar(50), description varchar(50), tax decimal(18,0))
INSERT INTO product
(idproduct, name, description,tax)
VALUES
(1, 'abc', 'This is abc',10),
(2, 'xyz', 'This is xyz',20),
(3, 'pqr', 'This is pqr',15)
CREATE TABLE product_storage
(idstorage int,idproduct int,added datetime, quantity int, price decimal(18,0))
INSERT INTO product_storage
(idstorage,idproduct, added, quantity,price)
VALUES
(1, 1, 2010-01-01,0,10.0),
(2, 1, 2010-01-02,0,11.0),
(3, 1, 2010-01-03,10,12.0),
(4, 2, 2010-01-04,0,12.0),
(5, 2, 2010-01-05,10,11.0),
(6, 2, 2010-01-06,10,13.0),
(7, 3, 2010-01-07,10,14.0),
(8, 3, 2010-01-07,10,16.0),
(9, 3, 2010-01-09,10,13.0)
and i am executing below command:-
declare #price1 varchar(10)
SELECT p.idproduct, p.name, p.tax,
[#price1]=(SELECT top 1 s.price
FROM product_storage s
WHERE s.idproduct=p.idproduct AND s.quantity > 0
ORDER BY s.added ASC),
(#price1 * (1 + tax/100)) AS [price_with_tax]
FROM product p
;
This is not working in MSSQL, Please Help me out.
for detail check http://sqlfiddle.com/#!6/91ec2/296
And My query is working in MYSQL
Check for detail :- http://sqlfiddle.com/#!9/a71b8/1
Try this query
SELECT
p.idproduct
, p.name
, p.tax
, (t1.price * (1 + tax/100)) AS [price_with_tax]
FROM product p
inner join
(
SELECT ROW_NUMBER() over (PARTITION by s.idproduct order by s.added ASC) as linha, s.idproduct, s.price
FROM product_storage s
WHERE s.quantity > 0
) as t1
on t1.idproduct = p.idproduct and t1.linha = 1
Try it like this:
Explanantion: You cannot use a variable "on the fly", but you can do row-by-row calculation in an APPLY...
SELECT p.idproduct, p.name, p.tax,
Price.price1,
(price1 * (1 + tax/100)) AS [price_with_tax]
FROM product p
CROSS APPLY (SELECT top 1 s.price
FROM product_storage s
WHERE s.idproduct=p.idproduct AND s.quantity > 0
ORDER BY s.added ASC) AS Price(price1)
;
EDIT: Your Fiddle uses a bad literal date format, try this:
INSERT INTO product_storage
(idstorage,idproduct, added, quantity,price)
VALUES
(1, 1, '20100101',0,10.0),
(2, 1, '20100102',0,11.0),
(3, 1, '20100103',10,12.0),
(4, 2, '20100104',0,12.0),
(5, 2, '20100105',10,11.0),
(6, 2, '20100106',10,13.0),
(7, 3, '20100107',10,14.0),
(8, 3, '20100108',10,16.0),
(9, 3, '20100109',10,13.0)
Here is the correct schema for SQL Server and query runs perfect as Shnugo Replied.
VALUES
(1, 1, convert(datetime,'2010-01-01'),0,10.0),
(2, 1, convert(datetime,'2010-01-02'),0,11.0),
(3, 1, convert(datetime,'2010-01-03'),10,12.0),
(4, 2, convert(datetime,'2010-01-04'),0,12.0),
(5, 2, convert(datetime,'2010-01-05'),10,11.0),
(6, 2, convert(datetime,'2010-01-06'),10,13.0),
(7, 3, convert(datetime,'2010-01-07'),10,14.0),
(8, 3, convert(datetime,'2010-01-07'),10,16.0),
(9, 3, convert(datetime,'2010-01-09'),10,13.0)
I have found a little here and a little there but nothing that really covers the question that I have so here goes. I have ordered a book from amazon but it won't be here for another week and I really need to this ASAP
I have two tables which contain basically the following.
Table A has the users id number, login name, wins, losses, ties
Table B has the User id number, when the game ended, game state
What I want is to create a stored procedure that will return the top 10 for wins for the last week.
Loginname | total wins, last 7 days | all wins | all losses | all ties
Name1 | 10 | 40 | 8 | 6
Name2 | 9 | 96 | 76 | 19
etc....
What I have so far is:
SELECT A.login,
A.draws_count,
A.losses_count,
A.wins_count
FROM [TableB] AS B
INNER JOIN
[TableA] AS A
ON B.won_by_id = A.id
WHERE B.win_defined_time > (GETDATE() - 7)
AND B.state = 'OVER';
From there I have no clue how to return the table that I need. Any assistance would be greatly appreciated. (also keep in mind that the 'total wins for the last 7 days' field does not exist in either table.)
Assuming a schema and sample data such as the following:
CREATE TABLE [dbo].[Competitors]
(
[id] INT NOT NULL,
[login_name] VARCHAR (50) NOT NULL,
[wins] INT NOT NULL,
[losses] INT NOT NULL,
[ties] INT NOT NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Events]
(
[id] INT NOT NULL,
[Competitorid] VARCHAR (50) NOT NULL,
[EventDateTime] DATETIME NOT NULL,
[winner] BIT NOT NULL,
[EventStatus] VARCHAR (50) NOT NULL
) ON [PRIMARY]
INSERT INTO Competitors (id, login_name, wins, losses, ties)
VALUES (1, 'Player 1', 40, 8, 6),
(2, 'Player 2', 96, 76, 19),
(3, 'Player 3', 1, 0, 0)
INSERT INTO Events (id, Competitorid, EventDateTime, winner, EventStatus)
VALUES (1, 1, '2013-01-25 01:05:25.000', 1, 'OVER'),
(2, 1, '2013-01-26 01:05:25.000', 1, 'OVER'),
(3, 1, '2013-01-27 14:05:25.000', 1, 'OVER'),
(4, 1, '2013-01-28 01:05:25.000', 1, 'OVER'),
(5, 1, '2013-01-29 15:05:25.000', 1, 'OVER'),
(6, 1, '2013-01-30 01:05:25.000', 1, 'OVER'),
(7, 1, '2013-01-31 22:05:25.000', 1, 'OVER'),
(8, 1, '2013-02-01 01:05:25.000', 1, 'OVER'),
(9, 1, '2013-02-02 21:05:25.000', 1, 'OVER'),
(10, 1, '2013-01-02 11:05:25.000', 0, 'INPROGRESS'),
(11, 1, '2013-01-30 01:05:25.000', 1, 'OVER'),
(12, 2, '2013-01-25 11:05:25.000', 1, 'OVER'),
(13, 2, '2013-01-26 01:05:25.000', 1, 'OVER'),
(14, 2, '2013-01-27 11:25:25.000', 1, 'OVER'),
(15, 2, '2013-01-28 01:05:25.000', 1, 'OVER'),
(16, 2, '2013-01-29 11:45:25.000', 1, 'OVER'),
(17, 2, '2013-01-30 01:45:25.000', 1, 'OVER'),
(18, 2, '2013-01-31 12:15:25.000', 1, 'OVER'),
(19, 2, '2013-02-01 01:05:25.000', 1, 'OVER'),
(20, 2, '2013-02-02 22:25:25.000', 1, 'OVER'),
(21, 2, '2013-02-02 15:05:25.000', 0, 'INPROGRESS'),
(22, 2, '2013-01-25 01:05:25.000', 1, 'OVER'),
(23, 1, '2013-01-30 01:05:25.000', 0, 'OVER'),
(24, 2, '2013-01-30 01:05:25.000', 0, 'OVER'),
(25, 3, '2012-01-30 01:05:25.000', 1, 'OVER')
You can return the names and wins data for the ten people with the most wins in the last 7 days using the following query:
SELECT TOP 10 login_name,
recent_wins,
wins AS 'All Wins',
losses AS 'All losses',
ties AS 'All Ties'
FROM Competitors
INNER JOIN
(SELECT COUNT(*) AS recent_wins,
Competitorid
FROM events
WHERE winner = 1
AND eventdatetime BETWEEN GetDate() - 7 AND GetDate()
AND EventStatus = 'OVER'
GROUP BY Competitorid) AS recent_event_winners
ON Competitors.ID = recent_event_winners.Competitorid;
ORDER BY recent_wins DESC
This query works by joining the data in the Competitors table together with a subquery on the data in the events table that is calaculating the number of recent wins and then taking the top 10 results. For users with a win in the last seven days, the subquery returns the count of the number of wins the user has had for events that are over during that time period.
Note: users without any wins during the time period will not be returned by either query so the results may have fewer than 10 results.
A SQL Fiddle with the above sql creation scripts and query can be found at http://sqlfiddle.com/#!3/0ebc8/2
I am trying to perform a filtering operation in SQL Server 2005.
Example. Let's say we have two tables, Current and Reject.
Current = 1, 2, 3, 4, 5, 1, 2
Reject = 2, 3, 4
Current \ Reject = 1, 2, 5
As you can see, the two tables share values. I essentially just want to subtract those shared values and place them into a new table.
This is what I tried, but it didn't work. (A is the column to match on).
select * from Current left join
Reject on csrp.a = rp.a
group by Current.a, Reject.a
having count(Current.a) > count(Reject.a)
Notice below that the element 2 was filtered out, even though it should not have been.
Martin Smith's answer worked for this case!
EDIT
Ok, so let's complicate it a little bit more. Let's say I have the exact same situation as before, except this time I need to match on three columns instead of just one?
Current = (1, 2, 3), (2, 3, 4), (2, 3, 4), (4, 5, 6), (7, 8, 9), (1, 2, 3)
Reject = (2, 3, 4), (4, 5, 6), (7, 8, 9)
Current \ Reject = (1, 2, 3), (2, 3, 4)
WITH [Current](a, b, c)
AS (SELECT 1, 2, 3 UNION ALL
SELECT 2, 3, 4 UNION ALL
SELECT 2, 3, 4 UNION ALL
SELECT 4, 5, 6 UNION ALL
SELECT 7, 8, 9 UNION ALL
SELECT 1, 2, 3),
Reject(a, b, c)
AS (SELECT 2, 3, 4 UNION ALL
SELECT 4, 5, 6 UNION ALL
SELECT 7, 8, 9 ),
T(RN, a, b, c)
AS (SELECT ROW_NUMBER() OVER (PARTITION BY a, b, c ORDER BY (SELECT 0)),
a,
b,
c
FROM [Current]
EXCEPT
SELECT ROW_NUMBER() OVER (PARTITION BY a, b, c ORDER BY (SELECT 0)),
a,
b,
c
FROM Reject)
SELECT DISTINCT a,
b,
c
FROM T