**id eid name value**
8 1 bbbb 3433
7 1 abce 1234
6 1 abcd efgh
Need to select value which has name = bbbb and abce.
I tried below query:
select * from emp where name in("bbbb","abce");
I am getting result as expected.
But if my query is below:
select * from emp where name in("bbbb","abce","abc");
my expected output is empty result because there is no name matches as abc in my above table.
But i am getting result which matches bbbb and abce.
What you do is simply select rows with a filter that uses the IN operator, but you requirement is different.
First get the eids that contain all the names in the list and then filter:
select * from emp
where name in('bbbb', 'abce', 'abc')
and eid in (
select eid from emp
where name in('bbbb', 'abce', 'abc')
group by eid
having count(distinct name) = 3
);
Check the demo.
A query:
select * from emp where name in("bbbb","abce","abc");
means that find emp's where name is any of those listed: bbbb or abce or abc
If you want to find emp's where each name listed appears at least once
select *
from emp
where name in("bbbb","abce","abc") and 3 = (
select count(distinct name)
from emp
where name in("bbbb","abce","abc")
)
IF you expect no result means you need to use AND condition :
select * from emp where name = "bbbb" and name="abce" and name = "abc";
Related
table 1 - employee
id empname
--------------
1 andy
2 brady
table 2 - employee phone numbers
id number empid
----------------
1 1111 1
2 2222 2
3 3333 1
4 4444 1
Need a sql query to display the following
id empname numbers
------------------
1 andy 1111,3333,4444
2 brady 2222
If you are using MySQL, you can use GROUP_CONCAT funcion, that basically concatenate every value composing the group. You could try this:
SELECT EMP.ID,
EMP.EMPNAME,
GROUP_CONCAT(EPH.NUMBER) AS NUMBERS
FROM EMPLOYEE EMP
JOIN EMPLOYEE_PHONE EPH
ON EMP.ID = EPH.EMPID
GROUP BY EMP.ID
Also, if you want to separate your values with something different of a "," you can add the syntax SEPARATOR " " after the column inside group concat, if you want to separate with spaces in this particular example
if you use SQL SERVER I think this will do it for you, if not maybe a close guess without data. But! I used STUFF and selected the Number and split them by , and ordered it
SELECT
t1.ID,t2v1.empname,
STUFF((SELECT ',' + t2v2.number
FROM Table2 t2v2
WHERE t2v2.ID = t2v1.ID
ORDER BY number
FOR XML PATH('')), 1, 1, '') [numbers]
FROM Table1 t1
inner join table2 t2v1 on t1.id = t2v1.id
GROUP BY t1.ID, t1.Name
ORDER BY 1
Try this:
SELECT e.id, e.name, CONCATENATE(ep.number, ',') as phonelist
FROM Employees e INNER JOIN EmployeePhone ep ON e.id = ep.empid
Reference Doc: http://www.peteonsoftware.com/index.php/2009/12/11/creating-a-comma-separated-list-from-a-sql-grouping/
I have an table like that:
id | name | v (lvl)
11 | Jane | 6
12 | John | 5
13 | Jane | 6
14 | John | 5
15 | Jane | 7
16 | Jane | 5
In my autocomplete form now id like to group the names but get the last value (value with biggest id). In the example above would be
Jane | 5
I tried with combinations like distinct, group by, order by. But im always get
Jane | 6
or grouped like this and reversed:
Jane | 6
Jane | 7
Jane | 5
I would need something like this:
SELECT name,lvl FROM
(
SELECT DISTINCT name, lvl FROM pora WHERE name LIKE 'Jane' ORDER BY lvl DESC
)
GROUP BY name
EDIT: I won't get the highest lvl, i want get the lvl of the highest id, grouped by name. Thats all. My example above would be the best explanation what i like to get.
In the inner query i change the order to DESC for all and in the outer i group it by names. But i get an error for this.
EDIT 2 I finally did at my own. The correct solution (i was already close):
SELECT a.name, a.lvl FROM
(
SELECT DISTINCT name, lvl FROM pora WHERE name LIKE 'Jane' ORDER BY id DESC
)as a
GROUP BY name
LIKE without % is just =
SELECT *
FROM yourTable
WHERE name = 'Jane'
ORDER BY id DESC
LIMIT 1
But because you mention autocomplete functionality you should use:
WHERE name LIKE 'Jane%'
To have the latest, you need to have a field dateAdded which stores the date you ran the insert command.
Following which, you use MAX(dateAdded) to get the latest ID (since, as you mentioned, it may decrease as well)
UPDATE:
if ID doesn't decrease, you can always use MAX(ID)
SELECT MAX(id), v from tablename where name = 'Jane'
UPDATE:
This has been tested:
SELECT ID, v from tableName where ID = (SELECT MAX(ID) as ID from tableName where name like '%Jane%')
Try the following query (h/t #lamak)
WITH CTE AS
(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY name
ORDER BY [id] DESC)
FROM poro
)
SELECT *
FROM CTE
WHERE RN = 1
UPDATED
id | id_list
1 | 2,3,5,7
2 | 1,4,5,6
3 | 1,4,6,7
4 | 2,3,5,8
5 | 1,2,4,8
6 | 2,3,7,8
7 | 1,3,6,9
8 | 4,5,6,9
9 | 7,8
let's say I'm up to the content of id=1
I wanted to select all the rows where id is in id_list of id=1 PLUS the row where id=1
so the result would be
rows with id = 1,2,3,5,7
How to do this query guys?
You can also use a self join
Using IN()
select * from atable a
join atable b on (a.id = b.id )
where 1 IN (a.id_list) or b.id =1
Fiddle with IN()
Using FIND_IN_SET()
select * from atable a
join atable b on (a.id = b.id )
where FIND_IN_SET('1', a.id_list) or b.id =1
Fiddle with FIND_IN_SET()
Using UNION ALL
select * from atable
where id =1
UNION ALL
select * from atable
where 1 IN (id_list)
Fiddle with UNION ALL
Your database design is broken; id_list should be represented as a join table instead of as a string. However, to solve your immediate problem:
select * from table where id=1
or id_list like '1%'
or id_list like '%,1,%'
or id_list like '%,1'
Adjust as needed for PreparedStatement. You have to provide all three cases because if you just did
or id_list like '%1%'
and id_list contained the value 11, you'd get an incorrect match
Try this (see SQL-Fiddle):
SELECT * FROM tbl
WHERE id = 1
OR INSTR((SELECT id_list FROM tbl WHERE id = '1'), id) > 0;
Tested with MySQL 5.5.30
try this one
select *
from tbl
where id=1
or id_list like '%1%'
This appears to call for a union of two sets. The one set would be the single row whose id matches the specified value:
SELECT
id
FROM
atable
WHERE
id = #id
The other set would be the result of this self-join:
SELECT
item.id
FROM
atable AS item
INNER JOIN
atable AS list
ON
FIND_IN_SET(item.id, list.id_list)
WHERE
list.id = #id
That is, the row with the specified id is matched against every row in the table on the condition that the other row's id is found in the specified row's id_list.
You can try the complete query at SQL Fiddle.
Please note that lists aren't a very good design feature. In your situation, it might be better to use a many-to-many table as suggested by #Othman. Only I would probably use a slightly different query to get the desired output, because his doesn't include the specified row itself:
SELECT
id
FROM
manytomany
WHERE
id = #id
UNION
SELECT
linked_id
FROM
manytomany
WHERE
id = #id
;
While the entries in manytomany are assumed to be unique, the query uses the UNION DISTINCT operator because of the potential duplicates returned by the first subquery, although it is possible to move the application of DISTINCT to the first subquery only like this:
SELECT DISTINCT
id
FROM
manytomany
WHERE
id = #id
UNION ALL
SELECT
linked_id
FROM
manytomany
WHERE
id = #id
;
That first subquery could actually be rewritten simply as SELECT #id AS id, but the rewrite would only make sense if the passed value was guaranteed to be valid, i.e. that it would definitely be found in manytomany.id.
Here's a demo for the other approach too (all three variations, including the SELECT #id AS id one).
I don't have an answer for your question but I encourage you to redesign your table like this I think this called many to many relation
id | friend
1 | 2
1 | 3
1 | 5
1 | 7
2 | 1
2 | 4
2 | 5
2 | 6
3 | 1
3 | 4
3 | 6
3 | 7
And then your query will be like this
SELECT DISTINCT(friend) FROM `new` WHERE id = 1
I am assuming you are using php..
My suggestion is to grab the id_list for id 1.
Explode that id_list on the comma, and then do another mysql query to grab the remaining results for 5|3|6|8
ex) $idarray = explode(",", $result);
select * from your_table where id in ('5','3','6','8')
OPTION 2:
SELECT * FROM your_table
WHERE id = '1'
OR id IN ('\''+(SELECT REPLACE(id_list,',','\',\'') FROM your_table WHERE id = '1')+'\'')
EDIT: Oops, sorry, that should be an OR instead.
I have a SQL Server 2008 table with the following columns:
ID = uniqueidentifier
EntryID = uniqueidentifier
EntryType = nvarchar(128)
In this table some of the rows may have the same EntryType value. What I want to do is run a query that will return me the rows where the EntryType field is unique. The only way I thought of doing this is to group by this field then check for groups with just a single entry. Here is some example data:
11C5AEEB-6435-489D-B353-6E8D63FCD1AD, 46F95579-0AB6-4EAC-927C-7259C2F1E046, Ford
01DBC8EE-78E4-4544-A816-87086BD45DDE, EBB689E3-1379-4E22-98B2-C6BD8EBB0F9D, VW
E948C6D2-0E6E-4AC7-9799-83C5EB180219, 46F95579-0AB6-4EAC-927C-7259C2F1E046, Ford
E70806DC-9D43-4341-AEF8-4252612AF00B, 3A3D2602-DB92-412B-AA4E-8FA70438A00A, Ford
D4460A15-2C4B-475E-B5D9-82C625C10DF7, 3EA31E10-4941-46D3-B241-B091259A2AF4, Lexus
I want to run a stored procedure that when applied to the above data will just return the VW entry as the EntryType column is unique.
;WITH x AS
(
-- first, identify rows where only one EntryType exists:
SELECT EntryType FROM dbo.table_name
GROUP BY EntryType HAVING COUNT(*) = 1
)
-- now join to that from the main table:
SELECT t.ID, t.EntryID, t.EntryType
FROM dbo.table_name AS t
INNER JOIN x
ON x.EntryType = t.EntryType;
In SQL Server 2008 you can use count() with over().
select T.ID, T.EntryID, T.EntryType
from
(
select ID, EntryID, EntryType,
count(*) over(partition by EntryType) as C
from YourTable
) as T
where T.C = 1
SQL Fiddle
The derived table will give you
ID EntryID EntryType C
-------- -------- --------- --
11C5AEEB.. 46F95579.. Ford 3
E948C6D2.. 46F95579.. Ford 3
E70806DC.. 3A3D2602.. Ford 3
D4460A15.. 3EA31E10.. Lexus 1
01DBC8EE.. EBB689E3.. VW 1
And the main query picks the rows where the count C is 1.
I have a table with columns id, user
I want to group by column id and show a list of users (comma separated) for each id.
In the final output I need to display:
user joe - id 1
users jim, mark, john - id 2
user dave - id 3
....
I'm getting error "Cardinality violation: 1242 Subquery returns more than 1 row" if I try this:
SELECT id, (SELECT distinct(user) FROM mytable b where a.id = b.id)
FROM mytable a
GROUP BY id
Since you are using MySQL, there is a built-in function for that which is the GROUP_CONCAT function. For example, you have a records like this:
ID User
1 Joe
2 Jim
2 Mark
2 John
3 Dave
If you try to run this query:
SELECT ID, GROUP_CONCAT(User) Users
FROM tableName
GROUP BY ID
you will then have a result like this:
ID Users
1 Joe
2 Jim, Mark, John
3 Dave
What you're looking for is the GROUP_CONCAT aggregate function:
SELECT id, GROUP_CONCAT(user) FROM table GROUP BY id