I have a tableA: (ID int, matchPID char,PID char, set int, num char, QID char, QStatus char)
ID matchPID PID set num QID QStatus
1 00001230 xx123 1 234
2 00001229 xx234 1 214
3 00000054 xx654 1 NULL
4 00012000 xx125 2
5 00A53214 xx321 2
6 00000100 xx213 2
matchPID is always (00-xxxxxx) x can be char or int.
now I have to populate OID just one value for each set according to [num].
If for any set, there exists any value in [num], then populate OID with PID where exists [num] for same set and populate Qstatus = 'fail' in rest.
so OID can be populated in id 1 or 2. (any1), then check lowest matchPID and populate here. so in this case (set1) expected result is :
ID matchPID PID set num QID QStatus
1 00001230 xx123 1 234 NULL FAIL
2 00001229 xx234 1 214 xx234 NULL
3 00000054 xx654 1 NULL NULL FAIL
if for any set there isnt any [num] found, then pick lowest matchPID and populate QID with PID and fail the rest.
notice that matchPID starts with 00 and then it can be 0>1>2>..>A>B>C>....
so expected result for set2 is :
ID matchPID PID set num QID QStatus
4 00012000 xx125 2 NULL NULL FAIL
5 00A53214 xx321 2 NULL NULL FAIL
6 00000100 xx213 2 NULL xx213 NULL
Thanks
Did you want something like this?:
;WITH setInfo AS (
SELECT [SET],
CASE WHEN EXISTS (SELECT 1 FROM tableA b
WHERE b.[set]=a.[set] AND num IS NOT NULL)
THEN 1 ELSE 0 END AS HasNum,
MIN(matchPID) AS MinMatchPID
FROM tableA a
GROUP BY [SET]
)
UPDATE a SET
QID = CASE WHEN s.HasNum = 0 AND a.matchPID = s.MinMatchPID THEN a.PID
WHEN s.HasNum = 0 AND a.matchPID != s.MinMatchPID THEN NULL
WHEN s.HasNum = 1 AND a.matchPID = (SELECT min(matchpid) FROM tableA b
WHERE b.[set] = a.[set]
AND b.num is not null
)
THEN a.PID
ELSE NULL
END,
QStatus = CASE WHEN s.HasNum = 0 AND a.matchPID = s.MinMatchPID THEN NULL
WHEN s.HasNum = 0 AND a.matchPID != s.MinMatchPID THEN 'FAIL'
WHEN s.HasNum = 1 AND a.matchPID = (SELECT min(matchpid) FROM tableA b
WHERE b.[set] = a.[set]
AND b.num is not null
)
THEN a.PID
ELSE 'FAIL'
END
FROM tableA a
JOIN setInfo s ON s.[set] = a.[set]
Related
I am trying to add two dynamic columns HeaderText and IsShowHeader to my table through a stored procedure.
In the first column, the first row must have text as Header1 and after 8 rows text must be Header2, then again after 8 rows text must be Header3 and so on.
In the second column value must be 1, and next 8 rows must have 0, the 9th row value must be 1 again, then the next 8 rows must have 0 like this...
ALTER PROCEDURE [dbo].[SkipRow]
AS
BEGIN
SELECT RID
,FirstName
,LastName
,(CASE WHEN X.[Row#]%9=0 And [X].[Row#]=0 THEN 1 ELSE
0 END)As IsShowHeader
,(COUNT(*) OVER ()) as TotalRows FROM
(
SELECT
*,ROW_NUMBER() OVER(ORDER BY RID) AS [Row#]
FROM Mytable1 WITH(NOLOCK)
)X
End
Output:
HeaderText IsShowHeader
1 Header1 1
2 Null 0
3 Null 0
4 Null 0
5 Null 0
6 Null 0
7 Null 0
8 Null 0
9 Null 0
10 Header2 1
11 Null 0
12 Null 0
13 Null 0
14 Null 0
15 Null 0
16 Null 0
17 Null 0
18 Null 0
19 Header3 1
you already have the [Row#], use the modulus operator % to get every 9 rows
HeaderText = case when ([Row#] - 1) % 9 = 0
then 'Header' + convert(varchar(10), ([Row#] - 1) / 9 + 1)
end,
IsShowHeader = case when ([Row#] - 1) % 9 = 0
then 1 else 0 end
You can try this:
SELECT M.id,
M.HeaderText,
CASE WHEN M.HeaderText IS NOT NULL THEN 1 ELSE 0 END AS IsShowHeader
FROM
(
SELECT P.id,
CASE
WHEN P.HeaderText IS NOT NULL THEN
P.HeaderText + CAST(P.IndexNumber AS VARCHAR(10))
ELSE
NULL
END AS HeaderText
FROM
(
SELECT K.id,
HeaderText,
COUNT(K.HeaderText) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS IndexNumber
FROM
(
SELECT id,
CASE
WHEN (id - 1) % 9 = 0 THEN 'Header' ELSE NULL
END AS HeaderText
FROM dbo.test
) AS K
) AS P
) AS M;
I have illustrate the scenario step by step, however you can rewrite it in a simple way like the answer that #Squirrel posted.
cid c2id
1 null
1 null
1 null
null 1
null 2
null 3
2 null
3 null
null 4
null 2
output:-
cid c2id
3 NA
NA 6
5 NA
NA 6
if add any one record it will also add and give out put like same
use two queries, one to sum, other to count nulls, then union them. There is no command which does it at once.
Here is one way that you could try
SELECT DISTINCT
ISNULL(CONVERT(VARCHAR, SUM(cid) OVER(PARTITION BY cid)), 'NA') cid,
ISNULL(CONVERT(VARCHAR, SUM(c2id) OVER(PARTITION BY cid)), 'NA') c2id
FROM <table_name>;
Result :
cid c2id
3 NA
NA 6
Assuming you have ID as Identity primary key column in your table for the order.
Query:
; WITH CTE AS
(
SELECT *,
CASE WHEN C2id IS NULL
THEN (SELECT top 1 ID FROM cid n WHERE n.c2id IS NOT NULL AND n.ID > CID.ID)
WHEN Cid IS NULL
THEN (SELECT top 1 ID FROM cid n WHERE n.cid IS NOT NULL AND n.ID > CID.ID)
END AS NextID
FROM CID
)
SELECT
CASE WHEN MIN(c2id) IS NULL THEN SUM(cid) ELSE -1 END AS cid,
CASE WHEN MIN(cid) IS NULL THEN SUM(c2id) ELSE -1 END AS c2id
FROM CTE
GROUP BY NextID
ORDER BY CASE WHEN NEXTID IS NULL THEN 1 ELSE 0 END, NextID
Sample Output:
cid c2id
3 -1
-1 6
5 -1
-1 6
You can replace -1 with NA. It calculates the next ID for required group and calculates sum in that group.
Please evaluate performance and correctness of query before using it.
I'm just wondering why still getting not correct result (0 row(s) affected)
with my update SQL. Please help I just need to update the Table A from Table B data with Price, and Size. After executing the update script I get 0 rows(s) affected. Why?
Table A:
TableAId CountNo Class RoomNo Section Price Sale Size
4 1 NULL 9 B 24347000 NULL NULL
5 1 NULL 9 C 26881000 NULL NULL
12 1 NULL 8 B 24245000 NULL NULL
16 1 NULL 8 A 39038000 NULL NULL
3 1 NULL 8 C 26495370 NULL NULL
21 1 NULL 6 D 36423000 NULL NULL
14 1 NULL 6 C 27200000 NULL NULL
1 1 NULL 5 C 30483000 NULL NULL
2 1 NULL 5 D 41052330 NULL NULL
Table B:
TableBId CountNo Class RoomNo Section Transaction Sale Size
12 1 NULL 9 B NULL 24347000 23800
20 1 NULL 9 C NULL 26881000 22800
44 1 NULL 9 NULL NULL 40079000 23100
69 1 NULL 9 D NULL 37614000 22100
21 1 NULL 8 C NULL 26763000 22700
28 1 NULL 8 D NULL 37444000 22000
13 1 NULL 8 B NULL 24245000 23700
5 1 NULL 8 A NULL 39038000 22500
6 1 NULL 7 A NULL 39558000 22800
Updated table:
TableAId CountNo Class RoomNo Section Price Sale Size
4 1 NULL 9 B 24347000 24347000 23800
5 1 NULL 9 C 26881000 26881000 22800
12 1 NULL 8 B 24245000 24245000 23700
16 1 NULL 8 A 39038000 39038000 22500
3 1 NULL 8 C 26495370 26763000 22700
21 1 NULL 6 D NULL NULL NULL
14 1 NULL 6 C NULL NULL NULL
1 1 NULL 5 C NULL NULL NULL
2 1 NULL 5 D NULL NULL NULL
SQL statement:
UPDATE x
SET x.Sale = y.Sale,
x.Size = y.Size
FROM TableA x
JOIN TableB y ON x.CountNo = y.CountNo
AND x.Class = y.Class
AND x.RoomNo = y.RoomNo
AND x.Section = y.Section
(0 row(s) affected)
try this: you need to compare null values separately
UPDATE x
SET
x.Sale = y.Sale,
x.Size = y.Size
FROM TableA x
JOIN TableB y
ON
x.CountNo = y.CountNo AND
(x.Class = y.Class OR (x.Class IS NULL and y.Class IS NULL)) AND
x.RoomNo = y.RoomNo AND
x.Section = y.Section
I believe that is happening because of NULL
UPDATE x
SET
x.Sale = y.Sale,
x.Size = y.Size
FROM
TableA x
JOIN TableB y ON x.CountNo = y.CountNo
AND ISNULL(x.Class,'') = ISNULL(y.Class,'')
AND x.RoomNo = y.RoomNo
AND ISNULL(x.Section,'') = ISNULL(y.Section,'')
You need add ISNULL(, ) If column is nullable
UPDATE x
SET
x.Sale = y.Sale,
x.Size = y.Size
FROM TableA x
JOIN TableB y
ON
ISNULL(x.CountNo, 0) = ISNULL(y.CountNo, 0) AND
ISNULL(x.Class, '') = ISNULL(y.Class, '') AND
ISNULL(x.RoomNo, 0) = ISNULL(y.RoomNo, 0) AND
ISNULL(x.Section, '') = ISNULL(y.Section, 0)
I have create a table and inserted some records.
CREATE TABLE #t
(
ID INT IDENTITY(1,1) PRIMARY KEY,
val INT NULL
);
-- INSERT 10 values: 3 NULL, 7 integers
INSERT INTO #t SELECT NULL;
INSERT INTO #t SELECT NULL;
INSERT INTO #t SELECT NULL;
INSERT INTO #t SELECT 5;
INSERT INTO #t SELECT 7;
INSERT INTO #t SELECT 8;
INSERT INTO #t SELECT 9;
INSERT INTO #t SELECT 9;
INSERT INTO #t SELECT 11;
INSERT INTO #t SELECT 12;
Now when i am executing script to find quartile
SELECT *,
NTILE(4) OVER (ORDER BY val) As Q
FROM #t;
i am getting values as
ID val Q
---------
1 NULL 1
2 NULL 1
3 NULL 1
4 5 2
5 7 2
6 8 2
7 9 3
8 9 3
9 11 4
10 12 4
I don't want "Null" records and don't want to use "Where" clause.
I want result like this
ID val Q
---------
4 5 1
5 7 1
6 8 2
7 9 2
8 9 3
9 11 3
10 12 4
It strikes me that you might want NULL for the NTILE() value and to ignore the values for the calculation. You can get this by doing:
SELECT t.*,
(CASE WHEN val IS NOT NULL
THEN NTILE(4) OVER (PARTITION BY (CASE WHEN val IS NOT NULL THEN 'NOTNULL' ELSE 'NULL' END)
ORDER BY val
)
END) as Q
FROM #t t;
Or, perhaps more simply:
SELECT id, val, NTILE(4) OVER (ORDER BY val) As Q
FROM #t t
WHERE val IS NOT NULL
UNION ALL
SELECT id, val, NULL as q
FROM #t t
WHERE val IS NULL;
You could try this:
SELECT *,
CASE
WHEN val IS NULL THEN NULL
ELSE NTILE(4) OVER (
--Split NULL and NOT NULL into 2 different groups
PARTITION BY CASE WHEN val IS NULL THEN 0 ELSE 1 END
ORDER BY val)
END AS Q
FROM #t
You'll get:
ID val Q
1 NULL NULL
2 NULL NULL
3 NULL NULL
4 5 1
5 7 1
6 8 2
7 9 2
8 9 3
9 11 3
10 12 4
Let's say I have this table MyTbl
Record Id_try Id Type IsOk DateOk
1 1 MYDB00125 A 0 NULL
2 1 MYDB00125 B 1 2012-07-19 20:10:05.000
3 1 MYDB00125 A 0 2012-07-25 14:10:05.000
4 2 MYDB00125 A 0 2012-07-19 22:10:05.000
5 1 MYDB00254 B 0 2012-07-19 22:10:05.000
6 1 MYDB00254 A 0 NULL
7 3 MYDB00125 A 1 2012-07-19 22:15:05.000
8 3 MYDB00125 B 1 2012-07-19 22:42:53.000
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 C 0 NULL
And I want a group by that brings me for each Id and Type my last "Id_Try Record".
SELECT Id, MAX(Id_Try), MyTbl.Type, IsOK, MAX(DateOk) from MyTbl
GROUP BY Id, MyTbl.Type, IsOK
Won't do, because It'll bring me the last Id_Try AND the last date (Date of record 3 in the example). And I don't care if its the last date or not, I need the date of the last Id_Try.
Is this only solved by a subselect? or a having clause could do?
This is the result expected:
Record Id_try Id Type IsOk DateOk
5 1 MYDB00254 B 0 2012-07-19 22:10:05.000
6 1 MYDB00254 A 0 NULL
7 3 MYDB00125 A 1 2012-07-19 22:15:05.000
8 3 MYDB00125 B 1 2012-07-19 22:42:53.000
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 B 0 NULL
I think you will need to break this into two pieces:
with maxIDTry as
(
SELECT MAX(Id_try) as maxId, ID
FROM MyTable
GROUP BY ID
)
SELECT * FROM MyTable as mt
INNER JOIN maxIDTry as max
ON mt.id_try = max.maxId AND mt.id = max.id
I think you want this:
select * FROM
(
select *, row_number() over (partition by id,type order by Id_try desc) as position from mytbl
) foo
where position = 1
order by record
http://www.sqlfiddle.com/#!3/95742/5
Your sample result set lists
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 A 0 NULL
But that doesn't make sense since you're saying the ID and the Id_try have the same value. I assume you meant for Id_try to be 2 maybe? Otherwise I think my results match up.
Hope this helps.
SELECT A.Record, A.Id_try, A.Id, A.Type, A.IsOk, A.DateOk
FROM MyTbl A INNER JOIN (
SELECT MAX(Id_Try) Id_Try, Id, B1.Type
from MyTbl B1
GROUP BY Id, B1.Type) AS B
ON A.Id_Try = B.Id_Try AND A.Id = B.Id AND A.Type = B.Type
ORDER BY A.RECORD