I have a single table: Checking, with two columns: ID, Memo
ID is the primary key.
I would like a query that returns both columns: ID, Memo BUT only where Memo is DISTINCT
I can do the following to get the distinct values from Memo:
SELECT DISTINCT(memo)
FROM checking
How do I return those Memo values and their values from the ID column?
I've run in circles trying inner and outer joins but I'm failing.
Thanks for your help
Sample data:
ID Memo
1 a
2 c
3 e
4 g
5 a
6 c
The desired return:
1,a
2,c
3,e
4,g
5 and 6 would not be included because they have duplicate memo values.
Thanks again for your help.
SELECT min(id), memo
FROM checking
group by memo
If I understand you correctly you want the first (?) primary key value corresponding to each unique memo value found? (I'm assuming this because you can't logically have both unique memos and Id values because there is necessarily multiple ID values for each duplicated memo value...) If the assumption is correct this will work:
SELECT m.memo,
(SELECT TOP 1 x.id
FROM checking x
WHERE x.memo = m.memo
ORDER BY x.id) as ID
FROM checking m
GROUP BY m.memo
SELECT ID,MEMO from CHECKING WHERE ID IN (SELECT MIN(ID) FROM CHECKING WHERE MEMO IN (SELECT DISTINCT MEMO FROM CHECKING))
Though nested, this query would server the purpose!
SELECT id,memo
FROM test
WHERE id IN
(
SELECT MIN(id)
FROM test
WHERE memo IN
(
SELECT DISTINCT memo
FROM test
)
GROUP BY memo
)
select id, memo
from checking
join
( /*only where Memo is DISTINCT*/
select distinct(memo) as memo
from checking
) as m on checking.memo = m.memo
Related
I'm trying to create a single row starting from multiple ones and combining them based on different column values; here is the result i reached based on the following query:
select distinct ID, case info when 'name' then value end as 'NAME', case info when 'id' then value end as 'serial'
FROM TABLENAME t
WHERE info = 'name' or info = 'id'
Howerver the expected result should be something along the lines of
I tried with group by clauses but that doesn't seem to work.
The RDBMS is Microsoft SQL Server.
Thanks
SELECT X.ID,MAX(X.NAME)NAME,MAX(X.SERIAL)AS SERIAL FROM
(
SELECT 100 AS ID, NULL AS NAME, '24B6-97F3'AS SERIAL UNION ALL
SELECT 100,'A',NULL UNION ALL
SELECT 200,NULL,'8113-B600'UNION ALL
SELECT 200,'B',NULL
)X
GROUP BY X.ID
For me GROUP BY works
A simple PIVOT operator can achieve this for dynamic results:
SELECT *
FROM
(
SELECT id AS id_column, info, value
FROM tablename
) src
PIVOT
(
MAX(value) FOR info IN ([name], [id])
) piv
ORDER BY id ASC;
Result:
| id_column | name | id |
|-----------|------|------------|
| 100 | a | 24b6-97f3 |
| 200 | b | 8113-b600 |
Fiddle here.
I'm a fan of a self join for things like this
SELECT tName.ID, tName.Value AS Name, tSerial.Value AS Serial
FROM TableName AS tName
INNER JOIN TableName AS tSerial ON tSerial.ID = tName.ID AND tSerial.Info = 'Serial'
WHERE tName.Info = 'Name'
This initially selects only the Name rows, then self joins on the same IDs and now filter to the Serial rows. You may want to change the INNER JOIN to a LEFT JOIN if not everything has a Name and Serial and you want to know which Names don't have a Serial
I Have a list of of SpellIDs with corresponding M values.
Given by the statement
SELECT TOP(1000) Spell_ID, MAX(Episode_Order) as M
From [dbo].[Client_MidEssex_Inpatient_Episodes_Landing]
GROUP BY Spell_ID
output
What I want to is to INSERT on the Episode Order Column on my Inpatients_episodes_table, a value depending on the M column from the select statement, on the corresponding spell_IDs. (Each row has a spell ID and Episode order value)
The logic is:For each spell ID value in the table Check the corresponding spellID in the select statement and -> check M value. Then Compare M value from the select statement to the Episode Order value from the table. Based on this comparison, insert either a discharge or admittance code
I am trying to relate the select statement and the table both on spell_IDs, but I'm not too how.
So far I have this:
UPDATE Inpatient_Episodes_Landing SET Episode_Ward = Null;
INSERT INTO [dbo].[Inpatient_Episodes_Landing] ([Episode_Ward])
SELECT
(Case when Episode_Order=01 then Admission_Ward_Code
when Episode_Order = (SELECT Spell_ID, MAX(Episode_Order) as M
From [dbo].[Client_MidEssex_Inpatient_Episodes_Landing]
where Spell_ID = (select SpellID from [dbo].[Inpatient_Episodes_Landing])
GROUP BY Spell_ID ) then Discharge_Ward_Code
else Admission_Ward_Code
END)
FROM [dbo].[Client_MidEssex_Inpatient_Episodes_Landing]
Select TOP (1000) SpellID,Episode_Number,Episode_Ward from Inpatient_Episodes_Landing
Any help would be great, thank you!
Am working with PostgreSQL 8.0.2, I have table
create table rate_date (id serial, rate_name text);
and it's data is
id rate_name
--------------
1 startRate
2 MidRate
3 xlRate
4 xxlRate
After select it will show data with default order or order by applied to any column of same table. My requirement is I have separate entity from where I will get data as (xlRate, MidRate,startRate,xxlRate) so I want to use this data to sort the select on table rate_data. I have tried for values join but it's not working and no other solution am able to think will work. If any one have idea please share detail.
Output should be
xlRate
MidRate
startRate
xxlRate
my attempt/thinking.
select id, rate_name
from rate_date r
join (
VALUES (1, 'xlRate'),(2, 'MidRate')
) as x(a,b) on x.b = c.rate_name
I am not sure if this is helpful but in Oracle you could achieve that this way:
select *
from
(
select id, rate_name,
case rate_name
when 'xlRate' then 1
when 'MidRate' then 2
when 'startRate' then 3
when 'xxlRate' then 4
else 100
end my_order
from rate_date r
)
order by my_order
May be you can do something like this in PostgreSQL?
I am writing a HIVE query to pull about 2,000 unique keys from a table.
I keep getting this error - java.lang.StackOverflowError
My query is basic but looks like this:
SELECT * FROM table WHERE (Id = 1 or Id = 2 or Id = 3 Id = 4)
my WHERE clause goes all the way up to 2000 unique id's and I receive the error above. Does anyone know of a more efficient way to do this or get this query to work?
Thanks!
You may use the SPLIT and EXPLODE to convert the comma separated string to rows and then use IN or EXISTS.
using IN
SELECT * FROM yourtable t WHERE
t.ID IN
(
SELECT
explode(split('1,2,3,4,5,6,1998,1999,2000',',')) as id
) ;
Using EXISTS
SELECT * FROM yourtable t WHERE
EXISTS
(
SELECT 1 FROM (
SELECT
explode(split('1,2,3,4,5,6,1998,1999,2000',',')) as id
) s
WHERE s.id = t.id
);
Make use of the Between clause instead of specifying all unique ids:
SELECT ID FROM table WHERE ID BETWEEN 1 AND 2000 GROUP BY ID;
i you can create a table for these IDs and after use the condition of exist in the new table to get only your specific IDs
Let's say I have a boolean field in a database table and I want to get a tally of how many are 1 and how many are 0. Currently I am doing:
SELECT 'yes' AS result, COUNT( * ) AS num
FROM `table`
WHERE field = 1
UNION
SELECT 'no' AS result, COUNT( * ) AS num
FROM `table`
WHERE field = 0;
Is there an easier way to get the result so that even if there are no false values I will still get:
----------
|yes | 3 |
|no | 0 |
----------
One way would be to outer join onto a lookup table. So, create a lookup table that maps field values to names:
create table field_lookup (
field int,
description varchar(3)
)
and populate it
insert into field_lookup values (0, 'no')
insert into field_lookup values (1, 'yes')
now the next bit depends on your SQL vendor, the following has some Sybase (or SQL Server) specific bits (the outer join syntax and isnull to convert nulls to zero):
select description, isnull(num,0)
from (select field, count(*) num from `table` group by field) d, field_lookup fl
where d.field =* fl.field
you are on the right track, but the first answer will not be correct. Here is a solution that will give you Yes and No even if there is no "No" in the table:
SELECT 'Yes', (SELECT COUNT(*) FROM Tablename WHERE Field <> 0)
UNION ALL
SELECT 'No', (SELECT COUNT(*) FROM tablename WHERE Field = 0)
Be aware that I've checked Yes as <> 0 because some front end systems that uses SQL Server as backend server, uses -1 and 1 as yes.
Regards
Arild
This will result in two columns:
SELECT SUM(field) AS yes, COUNT(*) - SUM(field) AS no FROM table
Because there aren't any existing values for false, if you want to see a summary value for it - you need to LEFT JOIN to a table or derived table/inline view that does. Assuming there's no TYPE_CODES table to lookup the values, use:
SELECT x.desc_value AS result,
COALESCE(COUNT(t.field), 0) AS num
FROM (SELECT 1 AS value, 'yes' AS desc_value
UNION ALL
SELECT 2, 'no') x
LEFT JOIN TABLE t ON t.field = x.value
GROUP BY x.desc_value
SELECT COUNT(*) count, field FROM table GROUP BY field;
Not exactly same output format, but it's the same data you get back.
If one of them has none, you won't get that rows back, but that should be easy enough to check for in your code.