How to use distinct clause only for one column - sql

I wanted to use distinct clause only for one column.I am having query like this
select id,brandname from brand.
Here brandname have same entry multiple time.I wanted to choose distinct brandname along with id.

You have to pick some way of getting only one ID, e.g.,
select max(id) , brandname
from brand
group by brandname
if you had more than one column you wanted... if the data was the same you could just continue to group by... however if extra columns had varying data you could use a slightly different strategy.
select * from brand
where id in
(
select max(id)
from brand
group by brandname
)

You can do this:
select Id,BrandName from brand group by BrandName,Id

Related

SELECT DISTINCT doesn't appear to work with big query

I am filtering to a second created table that have duplicates removed. However I'm finding that DISTINCT seems not be working, and I end up with rows with identical ids. I want to only select one unique ID and throw any remaining ones away, but this is not what is happening. In other-words I do not care about the other column names.
def de_dupe_affiliates(read_table, write_table):
query = """
CREATE OR REPLACE TABLE `{write_table}` AS
SELECT DISTINCT ID, BRAND, TITLE, SHORT_TITLE, PRICE, FROM `{read_table}`
""".format(read_table=read_table,write_table=write_table)
response = client.query(query).result()
I also tried
SELECT DISTINCT(ID), BRAND
But this did the same. Is it possible to do this with a DISTINCT on one column?
Consider below approach
SELECT AS VALUE ANY_VALUE(t) FROM (
SELECT ID, BRAND, TITLE, SHORT_TITLE, PRICE FROM read_table
) t
GROUP BY ID
Your select clause
SELECT DISTINCT ID, BRAND, TITLE, SHORT_TITLE, PRICE FROM `{read_table}`
is equivalent to
SELECT ID, BRAND, TITLE, SHORT_TITLE, PRICE FROM `{read_table}` GROUP BY ID, BRAND, TITLE, SHORT_TITLE, PRICE
meaning any differences within these fields creates new rows in your result.
Your query works only if ID, BRAND, TITLE, SHORT_TITLE, PRICE fields are unique.
If not, you may use window functions like row_number() or rank() to select one row per id.

SQL Query Multiple Columns Using Distinct on One Column Only and Using Order By

I am trying to select all the distinct names from a column and order them by another column, sort_order.
I've tried several things:
select distinct ( name ), sort_order from table1 where active=1 order by sort_order
The above code outputs two columns, however, some repeat names have different sort_order values and still appear.
select name, sort_order from table1 where
name in (Select min(name) FROM table1 where active=1 group by sort_order )
The above code produces the error message:
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
I tried replacing the order by with a group by, but this produces the list in the wrong order.
select distinct name as flavors from table1 where active=1 order by sort_order
The above code produces the error message:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
I need the name column to display all distinct names and the sort_order column should display all the corresponding sort_order numbers (some may repeat).
Use aggregation:
select name, max(sort_order)
from z_mflavs
where active = 1
group by name
order by max(sort_order); -- or min() or avg()
Note that in your query, the parentheses around (name) are utterly superfluous. SELECT DISTINCT is a clause in the SQL language and it applies to all columns being selected, regardless of whether any are expressions in parentheses.
Use this query...if you want values of name, sort_order column
SELECT name, MAX(sort_order) as sort_order FROM table1
Group by name ORDER BY MAX(sort_order) DESC

SQL Order By using concat

I'm concatenating two fields and I only want to order by the second field (p.organizationname). Is that possible?
I'm displaying this field so I need a solution that doesn't include me having to select the fields separately.
Here is what i have so far:
SELECT distinct Concat(Concat(f.REFERENCEFILE, ','),p.ORGANIZATIONNAME)
FROM PEOPLE p,FOLDER f,FOLDERPEOPLE fp,folderinfo fi...
Order By concat(Concat(f.REFERENCEFILE, ','),p.ORGANIZATIONNAME)
Use GROUP BY and ORDER BY an aggregate instead of DISTINCT:
SELECT Concat(Concat(f.REFERENCEFILE, ','),p.ORGANIZATIONNAME)
FROM PEOPLE p,FOLDER f,FOLDERPEOPLE fp,folderinfo fi...
GROUP BY Concat(Concat(f.REFERENCEFILE, ','),p.ORGANIZATIONNAME)
Order By MAX(p.ORGANIZATIONNAME)
The problem can be illustrated with an example:
ID Col1
1 Dog
1 Cat
2 Horse
Distinct ID? Easy: 1,2
Distinct ID Order by Col1... wait.. which value of Col1 should SQL use? SQL is confused and angry.
Since you are using a concatenation of two fields and want to sort by one of those fields, you could also include the sort field in a DISTINCT subquery and then ORDER BY the sort field without including it in your SELECT list.
Since you have a DISTINCT your ORDER BY clause should be specified in the SELECT, you can use a subquery to achieve the same result in your case since the Distinct values will be the same when you add P.ORGANIZATIONNAME
SELECT col
FROM( SELECT distinct Concat(Concat(f.REFERENCEFILE, ','),p.ORGANIZATIONNAME) a,
p.ORGANIZATIONNAME b
FROM PEOPLE p,FOLDER f,FOLDERPEOPLE fp,folderinfo fi... ) t
order by b

Aggregate SQL Function to grab only one from each grouping

I have a table that I need to normalize with many fields In SQL-Server 2000.
It contains 2 fields which I'm using to come up with distinct combination as defined by the specs.
ID and Rate: there are multiple rows of same IDs and Rates
I first created a temp table by grouping the IDs and Rates combination.
SELECT ID, Count(*) AS IDCounts, SUM(RATE) As Total
INTO #Temp
GROUP BY ID
Now I use Distinct to find only the unique combinations. So i'll have multiple ID groups sharing same Total and IDCounts
SELECT DISTINCT Total, IDCounts
INTO #uniques
FROM #Temp
Now my question is how to join a single ID back to that distinct grouping of IDCounts and Total and put that into a new table? It doesn't matter which one of the IDs in the groups as long as I use one from the same grouping.
Keeping your temp tables (although this could all be done in a single query):
SELECT ID, Count(*) AS IDCounts, SUM(RATE) As Total
INTO #Temp
GROUP BY ID
SELECT Total, IDCounts, MIN(ID) AS SomeID
INTO #uniques
FROM #Temp
GROUP BY Total, IDCounts
Add "Min(ID) AS FirstID" to the select into #uniques.
Try something like this:
SELECT MAX(ID) AS Id, Count(*) AS IDCounts, SUM(RATE) As Total
FROM SOMETABLE
GROUP BY IDCounts, Total

How do I select those records where the group by clause returns 2 or more?

I'd like to return a list of items of only those that have two or more in the group:
select count(item_id) from items group by type_id;
Specifically, I'd like to know the values of item_id when the count(item_id) == 2.
You're asking for something that's not particularly possible without a subquery.
Basically, you want to list all values in a column while aggregating on that same column. You can't do this. Aggregating on a column makes it impossible to list of all the individual values from that column.
What you can do is find all type_id values which have an item_id count equal to 2, then select all item_ids from records matching those type_id values:
SELECT item_id
FROM items
WHERE type_id IN (
SELECT type_id
FROM items
GROUP BY type_id
HAVING COUNT(item_id) = 2
)
This is best expressed using a join rather than a WHERE IN clause, but the idea is the same no matter how you approach it. You may also want to select distinct item_ids in which case you'll need the DISTINCT keyword before item_id in the outer query.
If your SQL dialect includes GROUP_CONCAT(), that could be used to generate a list of items without the inner query. However, the results differ; the inner query returns one item id per row, where GROUP_CONCAT() returns multiple ids as a string.
SELECT type_id, GROUP_CONCAT(item_id), COUNT(item_id) as number
FROM items
GROUP BY type_id
HAVING number = 2
Try this sql query:
select count(item_id) from items group by type_id having count(item_id)=2;