What i want to get?
Get id,name,email of the people who have sent me friend_requests.
Two tables i have used on the basis of which i want to get the details
signup -> id,name,email,firmname and a few more columns.
friends_requests ->id,userId,sentRequests,receivedRequests,friends,dates
Please refer to the below two images.
friends requests table
Signup table
What I am trying?
SELECT * FROM signup WHERE signup.id IN
(SELECT sentRequests FROM friends_request WHERE friends_request.userId=46)
This query only gives one record, whereas if i use below query it gives 3 records
SELECT * FROM signup WHERE signup.id IN (47,48,49)
I know why second query is giving three records because of the IN clause and three id's
But this query will also give the same result which is 47,48,49
SELECT sentRequests FROM friends_request WHERE friends_request.userId=46
But why isn't the first query giving three records?
When both the values are same? Then why isn't the result same?
About table friends_requests. Column sentRequests violates 1NF.
if I am right, IN operator gets your information as full string, not as separate ID information.
SELECT *
FROM signup
WHERE signup.id IN ('47,48,49')
what is operator thinks IN ('47,48,49')
what You think IN (47,48,49)
You have to split column value '47,48,49' into returning rows so operator could understand, if you want to use IN operator...
For it to work like you coded it,
SELECT sentRequests FROM friends_request WHERE friends_request.userId=46
would have to give 3 rows with 47,48,49.
Because sentRequests is a string it gives one row with 47,48,49
If you want the 3 values go with:
select * from #signup a where exists (select 1 from friends_request b where ','+sentRequests+',' like ',%'+cast(id as varchar(5))+',%')
try this...
SELECT * FROM signup WHERE id IN (
SELECT
DISTINCT cast(SUBSTRING_INDEX(SUBSTRING_INDEX(sentRequests, ',', n.digit+1), ',', -1) AS signed) sentRequests
FROM friends_request INNER JOIN (
SELECT
0 digit
UNION ALL
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 6
) n ON LENGTH(REPLACE(sentRequests, ',' , '')) <= LENGTH(sentRequests)-n.digit
WHERE userId = 46
);
Related
What I mean is, I have table with a "list" column. The data that goes into the "list" is related to addresses, so I sometimes get repeated zip codes for one record in that field.
For example, "12345,12345,12345,12456".
I want to know if it's possible to construct a query that would find the records that have an unknown string that duplicates within the field, such that I would get the records like "12345,12345,12345,12456", but not ones like "12345,45678,09876".
I hope that makes sense.
Yes, it is possible. You need to use a numbers table to convert your delimited string into rows, then use group by to find duplicates, e.g.
CREATE TABLE T (ID INT, List VARCHAR(100));
INSERT INTO T (ID, List)
VALUES (1, '12345,12345,12345,12456'), (2, '12345,45678,09876');
SELECT
T.ID,
SUBSTRING_INDEX(SUBSTRING_INDEX(T.list, ',', n.Number), ',', -1) AS ListItem
FROM T
INNER JOIN
( SELECT 1 AS Number UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5
) AS n
ON CHAR_LENGTH(T.list)-CHAR_LENGTH(REPLACE(T.list, ',', ''))>=n.Number-1
GROUP BY T.ID, ListItem
HAVING COUNT(*) > 1;
If you don't have a numbers table you can create one in a derived query as I have above with UNION ALL
Example on DB Fiddle
With that being said, this is almost certainly not the right way to store your data, you should instead use a child table, e.g.
CREATE TABLE ListItems
(
MainTableId INT NOT NULL, --Foreign Key to your current table
ItemName VARCHAR(10) NOT NULL -- Or whatever data type you need
);
Then your query is much more simple:
SELECT T.ID, li.ItemName
FROM T
INNER JOIN ListItems AS li
ON li.MainTableId = T.ID
GROUP BY T.ID, li.ItemName
HAVING COUNT(*) > 1;
If you need to recreate your original format, this is easily done with GROUP_CONCAT():
SELECT T.ID,
GROUP_CONCAT(li.ItemName) AS List
FROM T
INNER JOIN ListItems AS li
ON li.MainTableId = T.ID
GROUP BY T.ID;
Example on DB Fiddle
I am still unclear what your desired result is based on your question however if it is simply to get all rows where there is a duplicate entry in column list you could do the following:
SELECT * FROM TABLE
WHERE COLUMN IN
(SELECT COLUMN FROM TABLE
having count(*) >1)
I am looking for a way to run a simple SELECT statment. I have a table which has two columns: id and email.
I want to run a SELECT statment that won't return duplicate values. For example, take the following data:
1 example#hotmail.com
2 example12#hotmail.com
3 example#hotmail.com
4 example#hotmail.com
I want it to return only the following:
2 example12#hotmail.com
Use aggregation count(*) and check the result of aggregate function using having clause to filter out those records which are not duplicated
select *
from demo
group by email
having count(*) = 1
Demo
select id,email from table group by email having count(*) =1;
SELECT b.*,
( select a.USER_NAME
from A.db.USER a
where a.USER_ID=b.Booking_Inspector
) as USER_NAME
FROM A.dbo.Booking b
where b.Booking_Inspector=? and b.confirm=1
From this sql syntax, what is "," which after "*" mean?
and anyone can explain this query to me or tell me where I can start?
It means all the columns from table Booking, and to the far right (the last column per row) bring in the user_name column from table user relating on the user.user_id matching the booking.booking_inspector. Such that the Booking.confirm is 1, and Booking_inspector is filled in with a parameter passed.
So it limits the rows of output to confirm is 1 and Booking_Inspector is the parameter passed (or bound, etc) depending on the language calling it.
Select * means all columns. So all columns from the one table, and just one column from the other
In this case, (select a.USER_NAME from A.db.USER a where a.USER_ID=b.Booking_Inspector) is the subquery which will return column a.USER_NAME. So this query is selecting everything from b (b.*) and the column a.USER_NAME from the subquery. So like you put comma between column names in select query, it is same.
select all columns from b and one more column from that subquery as USER_NAME.
( select a.USER_NAME
from A.db.USER a
where a.USER_ID=b.Booking_Inspector
) as USER_NAME
That whole thing above as 1 column
SELECT b.*, [USER_NAME]
FROM A.dbo.Booking b
where b.Booking_Inspector=? and b.confirm=1
Is it possible to join Two queries of mysql in a query ??
Like:
select * from a + select * from b
So that I can use them in a single php loop.
If they have the same number of columns and the datatypes are the same in each column, then you can use a UNION or UNION ALL:
select *
from a
UNION ALL
select *
from b
If you provide more details about the tables, data, etc, then there might be another way of returning this data.
A UNION will return only the DISTINCT values, while a UNION ALL selects all values.
If this is the route that you need to take, and you still need to identify which table the data came from, then you can always create a column to identify which table the data is from , similar to this:
select *, 'a' TableName
from a
UNION ALL
select *, 'b' TableName
from b
This allows you to distinguish what table the data came from.
I think it is easier creating sql "variables" like:
select varA, varb from TableA, tableB;
and you can just play with values in PHP accessing properties.
That way you can take conditions in the query like:
select varA, varb from TableA, tableB where varA.id = varB.foreingId bla bla...
;)
Is it possible in MySQL to select from a static set of integers? Given an array of integers like 1 and 2, what is the correct syntax in MySQL to do something like:
select
*
from
(values(1),(2))
Which should return one row containing the number 1 and one row containing the number 2.
In other SQL than MySQL (e.g. MSSQL) this is possible. Is there a way to do this in MySQL?
I think you mean something like this?
SELECT 1 UNION SELECT 2 UNION SELECT 3
The only way to create a virtual set in MySQL is using a subquery with UNION. The subquery in the FROM clause creates 3 rows which can be joined with another table:
SELECT foo.*
FROM (
SELECT 1 AS num UNION
SELECT 2 AS num UNION
SELECT 3 AS num
) virtual
LEFT JOIN foo ON foo.num = virtual.num
When you want to use your list of values as a condition for WHERE or ON clause, then the IN() construct may be the right way to go:
SELECT foo.* FROM foo WHERE foo.num IN (1,2,3)
sorry for my english
you can use (IN) like this
SELECT * FROM Table WHERE id IN (1,2,3....)