Get first record per identifier group in SQL - sql

Code Description Whatever
---------------------------------
1 stuff blah
1 something meh
2 yah bong
2 never hammer time
How do I get a results set from this with each Code only present once? (I don't overly care which record for that code it is).
So I want....
1 stuff blah
2 yah bong

SELECT *
FROM (
SELECT * , row_number() over(partition by code order by Description) as id
from yourTable
) temp
WHERE id = 1
I think this is sql server only

You first need to pick a column which determines what counts as 'the first result'. In my example I chose Description:
SELECT * FROM YourTable first
WHERE
(SELECT COUNT(*) FROM YourTable previous
WHERE previous.Code=first.Code AND previous.Description < first.Description) = 0

Related

Select all values of a specific column associated with the max value of another column

I want to pull data from my table.
line Entryid
hello 1
world 1
this 1
is 1
hello 2
again 2
world 2
I want to select all the information associated with Entryid 2. Note i cannot say WHERE Project id = 2. I need something like where MAX(Entryid). So the information pulled will be hello again world
You can do what you want using join or a subquery:
select t.*
from t
where t.entryid = (select max(t2.entryid) from t t2);
You can use a sub query.
Select * From yourTable Where Entryid = (Select max (Entryid) From yourTable)

SQL Server : update multiple rows one by one while incrementing id

I am pretty new to SQL and I thought I was comfortable using it after a while but it still is tough. I am trying to increment ids. I know I could use auto-increment but in this case there are id has relationship with several categories so it has to start with different numbers so I can't do it.
The table looks something like this:
id category
----------------
1000 1
1000 1
...
2000 2
2000 2
...
And I want to make it:
id category
------------------
1000 1
1001 1
1002 1
...
2000 2
2001 2
...
I tried:
UPDATE T1
SET id = CASE
WHEN EXISTS (SELECT id FROM STYLE WHERE T1.id = id)
THEN (SELECT MAX(CAST(id AS INT)) + 1
FROM STYLE
WHERE category = T1.category)
END
FROM STYLE T1
WHERE idStyle = idStyle
But it just added 1 to all rows. How could I go 1 by 1 so it could actually get the incremented max id? Thank you.
In the absense of real sample data, this is a pseudo-sql, however, something like...
UPDATE YT
----SELECT NULL as Ihave no context of other fields in your table
SET id = id + ROW_NUMBER() OVER (PARTITION BY category ORDER BY (SELECT NULL)) - 1
FROM YourTable YT;
You can use row_number() function instead :
select *,
concat(cid, row_number() over (partition by id order by category)-1) as NewId
from style s;

Count how many times you exit route the car

i have a question, im on a project GPS,
When a car on route save in our database a value = 1, but when this go off route save in our database a value=0, so how can i determine the number of times out of route from an SQL query?
This is a example of our table:
Then if you look the pic, value 1 car is on route and 0 car is off route, i want count the values groups, for example my result will be:
Off Route = 2 (times)
There are several ways to do this. Depending on your database, there may be an easier version with window functions such as lead and lag. However, this should be generic with exists:
select count(y1.id)
from yourtable y1
where y1.value = 0 and exists (
select 1
from yourtable y2
where y2.id = y1.id - 1 and y2.value = 1)
;with cteBase as (
Select *,RowNr = Row_Number() over (Order by ID) From YourTable
)
Select A.*
From cteBase A
Join cteBase B on (A.RowNr=B.RowNr+1 and A.Value=0 and B.Value=1)
Returns
ID Value RowNr
4 0 4
6 0 6
I didn't want to assume the ID was incremental so I used Row_Number(). If incremental #sgeddes works just as well
If what you need is just the number of times Value is 1 as on Route and 0 as Off Route, try the following query:
select
sum(Value) as [On_route],
sum(abs(Value-1)) as [Off_Route]
from GPSTable
abs(Value-1) essentially coverts 0 to 1 and 1 to 0 which is easy enough to check,

SQL Server find the missing number

I have a table like below
id name year
--------------
1 A 2000
2 B 2000
2 B 2000
2 B 2000
5 C 2000
1 D 2001
3 E 2001
as well as you see in the year 2000 we missed id '3' and id '4' and in the year 2001 we missed id '2'. I want to generate my second table which includes missed items.
2nd table :
From-id to-id name year
--------------------------------
3 4 null 2000
2 null null 2001
Which method in a SQL query can solve my problem?
Gaps and Islands in Sequences is the name of this problem. you read this article
Here's something to get you started:
WITH cte AS
(
SELECT *
FROM
(VALUES
(1),(2),(3),(4),(5)
) Tally(number)
), cte2 as
(
SELECT DISTINCT [year]
FROM
(VALUES
(2000),(2000),(2001)
)tbl([year])
), cte3 as
(
SELECT *
FROM cte
CROSS JOIN cte2
)
SELECT *
FROM cte3
LEFT OUTER JOIN YourTable ON cte3.number = YourTable.id AND cte3.[year] = YourTable[year)
A few notes: please avoid using reserved keywords as column names (such as year).
Furthermore, since I didn't know how you'd handle multiple missing ranges I did not format the output to reflect a range. For example: What would be your expected output if only one row with id=3 would be in your table?
I'd probably use ROW_NUMBER for this
This query gives you what the correct ID should be (if I interpreted your question right):
SELECT
ROW_NUMBER() OVER (PARTITION BY yr ORDER BY name, yr) as "Correct ID", *
FROM misorder
It assigns a row number (so a number starting from 1 increasing by 1 every time the year is the same).
And to let you know which ones are missing I think this should be a working solution:
WITH missing AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY yr ORDER BY name, yr) as "Correct ID", *
FROM misorder
)
SELECT * FROM missing
WHERE "Correct ID" != "id"
It takes the first query as a base to select only those records where the assumed correct ID is not equal to the currently assigned ID. You can turn this into a query to include the ranges you mentioned, but not sure if that is really necessary.
Hope this helps.

SQL - Search a table for all instances where a value is repeated

I'm looking to find a way to search a table for duplicate values and return those duplicates (or even just one of the set of duplicates) as the result set.
For instance, let's say I have these data:
uid | semi-unique id
1 | 12345
2 | 21345
3 | 54321
4 | 41235
5 | 12345
6 | 21345
I need to return either:
12345
12345
21345
21345
Or:
12345
21345
I've tried googling around and keep coming up short. Any help please?
To get each row, you can use window functions:
select t.*
from (select t.*, count(*) over (partition by [semi-unique id]) as totcnt
from t
) t
where totcnt > 1
To get just one instance, try this:
select t.*
from (select t.*, count(*) over (partition by [semi-unique id]) as totcnt,
row_number() over (partition by [semi-unique id] order by (select NULL)
) as seqnum
from t
) t
where totcnt > 1 and seqnum = 1
The advantage of this approach is that you get all the columns, instead of just the id (if that helps).
Sorry, I was short on time earlier so I couldn't explain my answer. The first query groups the semi_unique_ids that are the same and only returns the ones that have a duplicate.
SELECT semi_unique_id
FROM your_table
GROUP BY semi_unique_id
HAVING COUNT(semi_unique_id) > 1
If you wanted to get the uid in the query too you can easily add it like so.
SELECT uid,
semi_unique_uid
FROM your_table
GROUP BY
semi_unique_id,
uid
HAVING COUNT(semi_unique_id) > 1
Lastly if you would like to get an idea of how many duplicates per row returned you would do the following.
SELECT uid,
semi_unique_uid,
COUNT(semi_unique_uid) AS unique_id_count
FROM your_table
GROUP BY
semi_unique_id,
uid
HAVING COUNT(semi_unique_id) > 1
SELECT t.semi_unique_id AS i
FROM TABLE t
GROUP BY
t.semi_unique_id
HAVING (COUNT(t.semi_unique_id) > 1)
Try this for sql-server