select group by in sql multiple columns - sql

I have three columns in one table (code, code alt and product). Code column has duplicate data. I want to leave all results without repeating the code column. I try with this
Select code, code alt, product from table
where code in
(
select code from table
group by code
having count (code)=1
)
but do not appear all results.
Thanks

If you want to leave only one row with the particular code from the bunch of rows with the same code you need to decide which one from multiple rows you want to leave.
You need some criteria by which you will be able to rank rows with the same code and select one from them by higher (for example) rank value. The script below will leave only one - random - row with specific code.
This is just an example that shows you the idea and it intended for SQL Server - because you do not pointed your DBMS
with [src] as (
select code, [code alt], product, rank() over(partition by code order by newid()) [rank]
from [table])
select * from [src] where [rank] = 1
Ranking Functions

Related

SQL Query for multiple columns with one column distinct

I've spent an inordinate amount of time this morning trying to Google what I thought would be a simple thing. I need to set up an SQL query that selects multiple columns, but only returns one instance if one of the columns (let's call it case_number) returns duplicate rows.
select case_number, name, date_entered from ticket order by date_entered
There are rows in the ticket table that have duplicate case_number, so I want to eliminate those duplicate rows from the results and only show one instance of them. If I use "select distinct case_number, name, date_entered" it applies the distinct operator to all three fields, instead of just the case_number field. I need that logic to apply to only the case_number field and not all three. If I use "group by case_number having count (*)>1" then it returns only the duplicates, which I don't want.
Any ideas on what to do here are appreciated, thank you so much!
You can use ROW_NUMBER(). For example
select *
from (
select *,
row_number() over(partition by case_number) as rn
) x
where rn = 1
The query above will pseudo-randomly pick one row for each case_number. If you want a better selection criteria you can add ORDER BY or window frames to the OVER clause.

SQL Query - Rank showing only 1 rank for all records

I am trying to perform ranking based on some calculation of already existing columns. I tried using the SQL RANK() function however it is showing the result as 1 for all entries even if the value of the order by (score column) is different. Please see the details below:
qu_point and ti_points are calculated columns
score column is again a derived column, however, simply sum of two columns mentioned in point 1.
I have used the SQL query as follow:
use EFR_DB
GO
select d.serial, d.question_set_id, d.correct_answers, d.total_questions, d.time_taken_seconds, q.total_time_in_secs,
(cast(d.correct_answers as float)/d.total_questions) as qu_point, ((q.total_time_in_secs-d.time_taken_seconds)/q.total_time_in_secs) as ti_point,
(((cast(d.correct_answers as float)/d.total_questions)*2) + ((q.total_time_in_secs-d.time_taken_seconds)/q.total_time_in_secs)) as score,
rank() over (partition by d.question_set_id order by score)
from daily_quiz_record d join Question_set q
on q.question_set_id=d.question_set_id
Please help me how can I do the raking which is partitioned by question_set_id and ranked on the basis of the score.
Screenshot attached for your reference.
enter image description here
You can’t use an alias defined in the select clause in the same clause. I suppose that one of your table has a column called score, otherwise your query would error - so this existing column is being used for ordering instead of the computed value.
Since your expression is lengthy, it is simpler to turn the query to a subquery, and rank in the outer query:
select
t.*,
rank() over(partition by question_set_id order by score) rn
from (
-- your existing query (without rank)
) t

Filtering SQL table by a changing argument

I have been trying to filter this database in orther to get a table just with the data in yellow (please see the table attached):
The rules I want to add to get these six rows are: each time the ticker column change I want to get the max maturity of that date.
I tried this code however it doesn't work...:
SELECT
DATE,
Ticker,
Maturity,
Value
FROM
Tables
WHERE
MAX(Maturity)
GROUP BY
Ticker
I am not sure that the image attached is visible since when I open my question it doesn't appear. If it doesn't appear please tell me.
SQL tables represent unordered sets. Your question pre-supposes an ordering to the data. Let me assume you have another column with this information.
Then you can just use lead():
select t.*
from (select t.*,
lead(ticker) over (order by <ordering column>) as next_ticker
from t
) t
where next_ticker is null or next_ticker <> ticker;

Get items before and after an item - SQL Query

I am new to SQL, so I need your help on a query. Basically I have a Database of ZipCodes and I want to get 3 items before the selected ZipCode and 3 items after. The Query that I came up with is pretty bad...
WITH numberedlogtable AS
(
SELECT *
FROM dbo.US
)
SELECT *
FROM numberedlogtable
WHERE ZipCode IN (SELECT ZipCode+i
FROM numberedlogtable
CROSS JOIN (SELECT -1 AS i UNION ALL SELECT 0 UNION ALL SELECT 1) n
WHERE ZipCode='91803')
I picked up a sample Query from somewhere and successfully converted it for my use. The only problem is that this Query returns current item and the next item. Instead, it should returns previous 3 items, current item, and next three items.
Using a common table expression (the WITH part) producing a numbered sequence:
WITH NumberedZipCodes AS
(SELECT SELECT ROW_NUMBER() OVER (ORDER BY ZipCode) AS RowNumber, *
FROM ZipCodes)
SELECT * From NumberedZipCodes
WHERE RowNumber BETWEEN
(SELECT RowNumber FROM NumberedZipCodes WHERE ZipCode=91803) - 3
AND (SELECT RowNumber FROM NumberedPerson WHERE ZipCode=91803) + 3
Normally in SQL there is no such concept as the previous or next items in a match. Actually, unless an order by clause is specified the rows are returned in any order that the sql engine find suitable. To make a query like this, an order has to be applied and index numbers generated. That's done in NumberedZipCodes. The second part is just a query to get the data out of it.
To have the query run efficiently, make sure that there is an index on the ZipCode column.
"Before" and "after" only have meaning in the context of ordering. Assuming you wish to order by ZIP code, selecting the desired ZIP code and 2 rows after it could be done like this:
SELECT TOP(3) *
FROM numberedlogtable
WHERE ZipCode >= '91803'
ORDER BY ZipCode
Selecting 3 rows before:
SELECT TOP(3) *
FROM numberedlogtable
WHERE ZipCode < '91803'
ORDER BY ZipCode DESC
Put UNION ALL between these two queries to make it one, if that's what you wish.
You can play with it in the SQL Fiddle.
3 items before the selected ZipCode and 3 items afte
SQL is set based, it has no defined order UNLESS YOU DEFINE ONE (with order by).
Now, lets not get into the more complex stuff - FURST you have to create an order asking for the central item, then in a second query you can ask for the other 6. Sorry, no other way. x+3 would be doable with a Top 4 statement and a filter etc. - but the 3 before will definitely require a second query.
All assume you creata query / view that has
* THe zipCodes in a defined order
* a row number once you filter it, used to define (a) the "current line" as well as filter for all with smaller lines.
But you need an order manually first.

SQL select first records of rows for specific column

I realize my title probably doesnt explain my situation very well, but I honestly have no idea how to word this.
I am using SQL to access a DB2 database.
Using my screenshot image 1 below as a reference:
column 1 has three instances of "U11124", with three different descriptions (column 2)
I would like this query to return the first instance of "U11124" and its description, but then also unique records for the other rows. image 2 shows my desired result.
image 1
image 2
----- EDIT ----
to answer some of the questions / posts:
technically, it does not need to be the first , just any single one of those records. the problem is that we have three descriptions, and only one needs to be shown, i am now told it does not matter which one.
SELECT STVNST, MAX(STDESC) FROM MY_TABLE GROUP BY STVNST;
In SQL Server:
select stvnst, stdesc
from (
select
stvnst, stdesc
row_number() over (order by stdesc partition by stvnst) row
from table
) a
where row = 1
This method has an advantage over a simple group by, in that it will also work when there's more than two columns in the table.
SELECT STVNST,FIRST(STDESC) from table group by STVNST ORDER BY what_you_want_first
All you need to do is use GROUP BY.
You say you want the first instance of the STDESC column? Well you can't guarntee the order of the rows without another column, however if you want to order by the highest ordered value the following will suffice:
SELECT STVNST, MAX(STDESC) FROM MY_TABLE GROUP BY STVNST;