I have a table with the below columns
+-------+------------+------------+
| AssID | QuestionID | AnswerText |
+-------+------------+------------+
| 12 | 34 | Null |
| 12 | 34 | Sample |
| 13 | 35 | null |
| 13 | 35 | test1 |
+-------+------------+------------+
I need to remove answertext null row with same AssId and QuestionID
Final Output needs to be in this format
+-------+------------+------------+
| AssId | QuestionID | AnswerText |
+-------+------------+------------+
| 12 | 34 | Sample |
| 13 | 35 | test1 |
+-------+------------+------------+
Please help me with the delete query
Thanks in advance
Sree
You can use exist to see if the NULL answerText row also has a Non-Null answerText Row
DELETE t
FROM MyTABLE t
WHERE t.AnswerText IS NULL
AND EXISTS
(
SELECT *
FROM MyTable m
WHERE m.AssID = t.AssID
AND m.QuestionID = t.QuestionID
AND m.AnswerText IS NOT NULL
)
You can use cte and row_number to delete
;with cte as (
select *, RowN = Row_number() over (partition by assid, questionid order by answertext) from yourtable
)--or order by your id because you have not provided logic for which one to select in answertext
delete from cte where RowN > 1
Related
I have table like:
name | timeStamp | previousValue | newValue
--------+---------------+-------------------+------------
Mark | 13.12.2020 | 123 | 155
Mark | 12.12.2020 | 123 | 12
Tom | 14.12.2020 | 123 | 534
Mark | 12.12.2020 | 123 | 31
Tom | 11.12.2020 | 123 | 84
Mark | 19.12.2020 | 123 | 33
Mark | 17.12.2020 | 123 | 96
John | 22.12.2020 | 123 | 69
John | 19.12.2020 | 123 | 33
I'd like to mix last_value, count (*) and group to get this result:
name | count | lastValue
--------+-----------+-------------
Mark | 5 | 33
Tom | 2 | 534
John | 2 | 69
This part:
select name, count(*)
from table
group by name
returns table:
name | count
--------+---------
Mark | 5
Tom | 2
John | 2
but I have to add the last value for each name.
How to do it?
Best regards!
LAST_VALUE is a windowed function, so you'll need to get that value first, and then aggregate:
WITH CTE AS(
SELECT [name],
[timeStamp], --This is a poor choice for a column's name. timestamp is a (deprecated) synonym of rowversion, and a rowversion is not a date and time value
previousValue,
newValue,
LAST_VALUE(newValue) OVER (PARTITION BY [name] ORDER BY [timeStamp] ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS lastValue
FROM dbo.YourTable)
SELECT [Name],
COUNT(*) AS [count],
lastValue
FROM CTE
GROUP BY [Name],
lastValue;
I got a solution that works, but here's another one:
SELECT
[name], COUNT([name]), [lastValue]
FROM (
SELECT
[name], FIRST_VALUE([newValue]) OVER (PARTITION BY [name] ORDER BY TimeStamp DESC ROWS UNBOUNDED PRECEDING) AS [lastValue]
FROM [table]
) xyz GROUP BY [name], [lastValue]
Keep well!
I have a table dbo.X with DateTime column lastUpdated and a code product column CodeProd which may have hundreds of records, with CodeProd duplicated because the table is used as "stock history"
My Stored Procedure has parameter #Date, I want to get all CodeProd nearest to that date so for example if I have:
+----------+--------------+--------+
| CODEPROD | lastUpdated | STATUS |
+----------+--------------+--------+
| 10 | 2-1-2019 | C1 |
| 10 | 1-1-2019 | C2 |
| 10 | 31-12-2019 | C1 |
| 11 | 31-12-2018 | C1 |
| 11 | 30-12-2018 | C1 |
| 12 | 30-8-2018 | C3 |
+----------+--------------+--------+
and #Date= '1-1-2019'
I wanna get:
+----+--------------+------+
| 10 | 1-1-2019 | C2 |
| 11 | 31-12-2018 | C1 |
| 12 | 30-8-2018 | C3 |
+----+--------------+------+
How to find it?
You can use TOP(1) WITH TIES to get one row with nearest date for each CODEPROD which should be less than provided date.
Try like following code.
SELECT TOP(1) WITH TIES *
FROM [YourTableName]
WHERE lastupdated <= #date
ORDER BY Row_number()
OVER (
partition BY [CODEPROD]
ORDER BY lastupdated DESC);
You can use apply :
select distinct t.CODEPROD, t1.lastUpdated, t1.STATUS
from table t cross apply
( select top (1) t1.*
from table t1
where t1.CODEPROD = t.CODEPROD and t1.lastUpdated <= #date
order by t1.lastUpdated desc
) t1;
I have a table named tableX structed like this. Notice the relation of childNo and parentNo columns.
childNo | parentNo |locationId |value
--------+----------+-----------+--------+
26 | NULL | 7 | value1 |
27 | NULL | 7 | value2 |
28 | 27 | 7 | value3 |
29 | 27 | 7 | value4 |
30 | 27 | 7 | value5 |
34 | NULL | 7 | value6 |
and I want to copy the same value column information to a different locationId(let's say locationId = 3) with new childNo and parentNo (protecting the relation)
Expected output.
childNo | parentNo |locationId |value
--------+----------+-----------+--------+
36 | NULL | 3 | value1 |
37 | NULL | 3 | value2 |
38 | 37 | 3 | value3 |
39 | 37 | 3 | value4 |
40 | 37 | 3 | value5 |
44 | NULL | 3 | value6 |
How can I achieve that using T-SQL?
Perhaps I'm missing something, but you could just do:
insert into t(childNo, parentNo, locationId, value)
select t.childNo + 10, t.ParentNo + 10, 3, t.value
from t
where t.locationId = 7;
I try this sample in SQL Server 2012.
DECLARE #lastParent int;
DECLARE #lastChild int;
DECLARE #newLocationId int;
SET #newLocationId = 3;
SELECT #lastParent = MAX(ParentNo) FROM tableX WHERE ParentNo IS NOT NULL;
SELECT #lastChild = MAX(ChildNo) from tableX;
INSERT INTO tableX (childNo, parentNo , LocationId, valueColumn)
SELECT
#lastChild + ROW_NUMBER() OVER (PARTITION BY LocationId ORDER BY childNo) AS childNo,
CASE WHEN (ParentNo IS NOT NULL) then #lastParent + 1
ELSE ParentNo
END as NewParentNo,
#NewLocationId as NewLocationId, valueColumn
FROM tableX
WHERE LocationId = 7
ORDER BY childNo
Two instances of this code running at same time, can produce duplicates values. I think your table must have Unique constraint on childNo and some trigger to validate parentNo
I have a table with a million records. I need to update some columns which are null based on the existing 'not null' records of a particular id based columns. I've tried with one query, it seems to be working fine but I don't have confidence in it that it will be able to update all those 1 million records exactly the way I need. I'm providing you some sample data how my table looks like.Any help will be appreciated
SELECT * INTO #TEST FROM (
SELECT 1 AS EMP_ID,10 AS DEPT_ID,15 AS ITEM_NBR ,NULL AS AMOUNT,NULL AS ITEM_NME
UNION ALL
SELECT 1,20,16,500,'ABCD'
UNION ALL
SELECT 1,30,17,NULL,NULL
UNION ALL
SELECT 2,10,15,1000,'XYZ'
UNION ALL
SELECT 2,30,16,NULL,NULL
UNION ALL
SELECT 2,40,17,NULL,NULL
) AS A
Sample data:
+--------+---------+----------+--------+----------+
| EMP_ID | DEPT_ID | ITEM_NBR | AMOUNT | ITEM_NME |
+--------+---------+----------+--------+----------+
| 1 | 10 | 15 | NULL | NULL |
| 1 | 20 | 16 | 500 | ABCD |
| 1 | 30 | 17 | NULL | NULL |
| 2 | 10 | 15 | 1000 | XYZ |
| 2 | 30 | 16 | NULL | NULL |
| 2 | 40 | 17 | NULL | NULL |
+--------+---------+----------+--------+----------+
Expected result:
+--------+---------+----------+--------+----------+
| EMP_ID | DEPT_ID | ITEM_NBR | AMOUNT | ITEM_NME |
+--------+---------+----------+--------+----------+
| 1 | 10 | 15 | 500 | ABCD |
| 1 | 20 | 16 | 500 | ABCD |
| 1 | 30 | 17 | 500 | ABCD |
| 2 | 10 | 15 | 1000 | XYZ |
| 2 | 30 | 16 | 1000 | XYZ |
| 2 | 40 | 17 | 1000 | XYZ |
+--------+---------+----------+--------+----------+
I tried this but I'm unable to conclude whether it is updating all the 1 million records properly.
SELECT * FROM #TEST T
inner JOIN #TEST T1 ON T1.EMP_ID=T.EMP_ID
WHERE T1.AMOUNT IS NOT NULL
UPDATE T SET AMOUNT=T1.AMOUNT
FROM #TEST T
inner JOIN #TEST T1 ON T1.EMP_ID=T.EMP_ID
WHERE T1.AMOUNT IS not NULL
I have used UPDATE using inner join
UPDATE T
SET T.AMOUNT = X.AMT,T.ITEM_NME=X.I_N
FROM #TEST T
JOIN
(SELECT EMP_ID,MAX(AMOUNT) AS AMT,MAX(ITEM_NME) AS I_N
FROM #TEST
GROUP BY EMP_ID) X ON X.EMP_ID = T.EMP_ID
SELECT * into #Test1
FROM #TEST
WHERE AMOUNT IS NOT NULL
For records validation run this query first
SELECT T.AMOUNT, T1.AMOUNT, T1.EMP_ID,T1.EMP_ID
FROM #TEST T
inner JOIN #TEST1 T1 ON T1.EMP_ID=T.EMP_ID
WHERE T.AMOUNT IS NULL
Begin Trans
UPDATE T
SET T.AMOUNT=T1.AMOUNT, T.ITEM_NME= = T1.ITEM_NME
FROM #TEST T
inner JOIN #TEST1 T1 ON T1.EMP_ID=T.EMP_ID
WHERE T.AMOUNT IS NULL
rollback
SELECT EMP_ID,MAX(AMOUNT) as AMOUNT MAX(ITEM_NAME) as ITEM_NAME
INTO #t
FROM #TEST
GROUP BY EMP_ID
UPDATE t SET t.AMOUNT = t1.AMOUNT, t.ITEM_NAME = t1.ITEM_NAME
FROM #TEST t INNER JOIN #t t1
ON t.emp_id = t1.emp_id
WHERE t.AMOUNT IS NULL and t.ITEM_NAME IS NULL
Use MAX aggregate function to get amount and item name for each employee and then replace null values of amount and item name with those values. For validation use COUNT function to calculate the number of rows with values of amount and item name as null. If the number of rows is zero then table is updated correctly
I have table with 5 columns like this
+----+-------------------------+-----------+--------+-----------+
| Id | CreateDate | CompanyId | UserId | IsEnabled |
+----+-------------------------+-----------+--------+-----------+
| 1 | 2016-01-02 23:40:46.517 | 1 | 1 | 1 |
| 2 | 2016-01-16 00:07:59.857 | 1 | 2 | 1 |
| 3 | 2016-01-25 15:17:54.420 | 3 | 3 | 1 |
| 25 | 2016-03-07 16:48:39.260 | 24 | 10 | 0 |
| 26 | 2016-03-07 16:48:39.263 | 25 | 2 | 0 |
+----+-------------------------+-----------+--------+-----------+
(thanks http://www.sensefulsolutions.com/2010/10/format-text-as-table.html for ASCII table!)
I'm trying to check if a UserId is recorded for more than one CompanyId's.
So far I managed to check if a UserId happens to appear more than one by using this query
WITH T AS
(
SELECT * ,
Count(*) OVER (PARTITION BY UserId) as Cnt
From CompanyUser
)
select Distinct UserId
FROM T
Where Cnt >1
It returns 2 correctly.
Where I'm stuck is, how can I parameterize the UserId and check if an Id is recorded for more than one company.
Declare #UserID as bigint
Set #UserID = 2
select Distinct Count(CompanyID)
FROM ComapynUser
Where UserId = #UserId
I think this gives you what you need.