Give first duplicate a 1 and the rest 0 - sql

I have data which contains 1000+ lines and in this it contains errors people make. I have added a extra column and would like to find all duplicate Rev Names and give the first one a 1 and all remaining duplicates a 0. When there is no duplicate, it should be a 1. The outcome should look like this:
RevName ErrorCount Duplicate
Rev5588 23 1
Rev5588 67 0
Rev5588 7 0
Rev5588 45 0
Rev7895 6 1
Rev9065 4 1
Rev5588 1 1
I have tried CASE WHEN but its not giving the first one a 1, its giving them all zero's.
Thanks guys, I am pulling out my hair here trying to get this done.

You could use a case expression over the row_number window function:
SELECT RevName,
Duplicate,
CASE ROW_NUMER() OVER (PARTITION BY RevName
ORDER BY (SELECT 1)) WHEN 1 THEN 1 ELSE 0 END AS Duplicate
FROM mytable

SQL tables represent unordered sets. There is no "first" of anything, unless a column specifies the ordering.
Your logic suggests lag():
select t.*,
(case when lag(revname) over (order by ??) = revname then 0
else 1
end) as is_duplicate
from t;
The ?? is for the column that specifies the ordering.

Related

SQL SUM only when each value within a group is greater than 0

Here is a sample data set:
ID Value
1 421
1 532
1 642
2 3413
2 0
2 5323
I want a query that, in this case, only sums ID=1 because all of its values are greater than 0. I cannot use a WHERE statement that says WHERE Value > 0 because then ID=2 would still return a value. I feel like this may be an instance where I could possibly use a OVER(PARTITION BY...) statement, but I am not familiar enough to use it creatively.
As an aside, I don't simply add a WHERE ID = 1 statement because this needs to cover a much larger data set.
Just use having:
select id, sum(value)
from t
group by id
having min(value) > 0;

Need to result of column based on available column in SQL

I am having one view which is returning the following result:
I need to put identifier just like below image
Required output:
Explanation of Output: If you can see the image 1 and in that image release 1 has 3 dates. From that I need to get 1 as an identifier for the MAX(IMPL_DATE).In RELEASE_ID = 1, We are having 08/20/2016, 08/09/2016 and 10/31/2016. From This 10/31/2016 is the largest date. So, Need Identifier as 1 and other 2 are going to be 0. Same thing with the RELEASE_ID 2 we have 2 dates and from them 01/13/2017 is the largest date so, need 1 in that row and other's going to be 0.
Thanks In advance...
You can do this with window functions:
select t.*,
(case when rank() over (partition by portfolio_id, release_id
order by impl_date desc
) = 1
then 1 else 0
end) as indentifier
from t;
The above will assign "1" to all rows with the maximum date. If you want to ensure that only one row is assigned a value (even when there are ties), then use row_number() instead of rank().

Counting non-zero values in sql

I am trying to count total number of times that each individual column is greater than zero, grouped by the driver name. Right now I have;
SELECT drivername
, COUNT(over_rpm) AS RPMViolations
, COUNT(over_spd) AS SpdViolations
, COUNT(brake_events) AS BrakeEvents
FROM performxbydriverdata
WHERE over_rpm > 0
OR over_spd > 0
OR brake_events > 0
GROUP BY drivername
This gives me all of the non-zero values but I get a display as:
Bob Smith 62 62 62
Nathan Jones 65 65 65
etc.
I'm trying to get a count of non-zeros in each individual values.. each violation should be grouped separately.
Use NULLIF to change zero to NULL, count ignores NULL
SELECT drivername,
COUNT(NULLIF(over_rpm,0)) AS RPMViolations,
COUNT(NULLIF(over_spd,0)) AS SpdViolations,
COUNT(NULLIF(brake_events,0)) AS BrakeEvents
FROM performxbydriverdata
GROUP BY drivername;
You can probably remove the WHERE clause too with this group to improve performance
OR conditions often run badly because of matching a good index
Using HAVING (as per other answers) will remove any rows where all 3 aggregates are zero which may or may not be useful for you. You can add this if you want. Saying that, the WHERE implies that at least one row has non-zero values so you don't need both WHERE and HAVING clauses
Putting filter predicate[s] inside of a Sum() function with a case statement is a useful trick anytime you need to count items based on some predicate condition.
Select DriverName,
Sum(case When over_rpm > 0 Then 1 Else 0 End) OverRpm,
Sum(case When over_spd > 0 Then 1 Else 0 End) OverSpeed,
Sum(case When brake_events > 0 Then 1 Else 0 End) BrakeEvents,
etc.
FROM performxbydriverdata
Group By DriverName

SQL: Sort by priority, but put 0 last

I have a (int) column called "priority". When I select my items I want the highest priority (lowest number) to be first, and the lowest priority (highest number) to be the last.
However, the items without a priority (currently priority 0) should be listed by some other column after the ones with a priority.
In other words. If I have these priorities:
1 2 0 0 5 0 8 9
How do I sort them like this:
1 2 5 8 9 0 0 0
I guess I could use Int.max instead of 0, but 0 makes up such a nice default value which I would try to keep.
I don't think it can get cleaner than this:
ORDER BY priority=0, priority
SQLFiddle Demo
Note that unlike any other solutions, this one will take advantage of index on priority and will be fast if number of records is large.
Try:
order by case priority when 0 then 2 else 1 end, priority
A very simple solution could be to use a composite value/ "prefix" for sorting like this:
SELECT ...
FROM ...
ORDER By CASE WHEN priority = 0 THEN 9999 ELSE 0 END + priority, secondSortCriteriaCol
This will do the trick. You will need to replace testtable with your table name.
SELECT t.priority
FROM dbo.testtable t
ORDER BY (CASE WHEN t.priority = 0 THEN 2147483647 ELSE t.priority END)
In case it's not clear I've picked 2147483647 because this is the max value of the priority column so it will be last.
Mark's answer is better and defo one to go with.
order by case(priority) when 0 then 10 else priority end

Reorder integer except for value 0 with sql

I'm trying to get an ordered list of rows out of my MYSQL database table based upon an integer value 'place'.
SELECT * FROM mytable
ORDER BY place;
This works okay, except that all rows with value place=0 should appear at the end of the table.
So if my table is:
name place
---- -----
John 1
Do 2
Eric 0
Pete 2
it should become:
name place
---- -----
John 1
Do 2
Pete 2
Eric 0
order by case when place = 0 then 1 else 0 end asc, place asc
that way you get all the non-zeroes ordered first.
SELECT *
FROM myTable
ORDER BY place>0 DESC, place
is a solution without CASE
SELECT *
FROM myTable
ORDER BY CASE place WHEN 0 THEN 9999 ELSE place END
This approach implies that we known that 9999 (or some other value) is bigger than all possible values in the place column.
Alternatively we can sort by two values as in:
ORDER BY CASE place WHEN 0 THEN 0 ELSE -1 END, place