Database combine two queries into one - mysql

I have table that has 2 fields userId and ebayitemId. Following is table from database:
userId | ebayitemId
12 | 1
12 | 2
12 | 3
12 | 4
In my situation, the client makes request with ebayitemId to see what other items are listed with this user.( ebayitemId is unique ). So far I am using two query to select all items listed by the user. First query is
SELECT userId WHERE ebayitemId = '1'
This query gets me USERID FOR THAT EBAYITEMID.
The second query is
SELECT ebayitemId WHERE userId = '$userid'
This gives me ebayitemId 1,2,3 and 4.
My question: Is there a way to combine these two queries into one query to get above result since only one table is involved?

The query :
SELECT iu.ebayitemId
FROM t_items AS iu
INNER JOIN t_items AS ii ON (iu.userId=ii.userId)
WHERE (ii.ebayitemId= $item )
and if you don't want the first item to be selected :
SELECT iu.ebayitemId
FROM t_items AS iu
INNER JOIN t_items AS ii ON (iu.userId=ii.userId)
WHERE (ii.ebayitemId= $item )
AND (iu.ebayitemId<>ii.ebayitemId)
Note : an IN statement would be less optimized.

It can be done with
SELECT ebayitemId from table WHERE userId in (SELECT userId from table WHERE ebayitemId = '1')

Naively:
SELECT ebayitemId
FROM yourtable
WHERE userId IN (
SELECT userId
FROM yourtable
WHERE ebayitemId = '1'
)
Note there are other ways to skin this cat with joins etc.

Related

count of individual column with group by on multiple columns

I have two columns account_number and customer_id. A single customer can have multiple account but a single account can't have multiple customer.
I have dumped a file containing account_num and its corresponding customer_id to db through LOAD DATA INFILE command. Now I am trying to validate through query does any account which has come multiple times in a file has same customer_id or different customer_id in two different rows.
REQUIREMENT : i want to return those accounts which has come multiple times but having diferent customer ids
I tried with group by , but didn't get desired result.
This is my query which is not giving the desired result
SELECT ACCOUNT_NUM,UNIQUE_CUSTOMER_ID,COUNT(UNIQUE_CUSTOMER_ID)
FROM LINKAGE_FILE
GROUP BY ACCOUNT_NUM, UNIQUE_CUSTOMER_ID
HAVING COUNT(ACCOUNT_NUM) > 1 AND COUNT(UNIQUE_CUSTOMER_ID) = 1;
Hope I am clear.
You can simply get the count of unique customer ids using COUNT(DISTINCT..) for every account_num and filter out those cases where count is more than 1, inside the HAVING clause:
SELECT
ACCOUNT_NUM,
COUNT(DISTINCT CUSTOMER_ID) AS unique_customer_count
FROM LINKAGE_FILE
GROUP BY ACCOUNT_NUM
HAVING unique_customer_count > 1
Drop the customer check into a join query like so
DROP TABLE if exists t;
create table t(accountid int,cid int);
insert into t values
(1,1),(1,2).(1,1),(2,3),(3,4),(3,4);
select distinct t.accountid,t.cid
from t
join
(
select accountid,count(distinct cid) cids
from t
group by accountid having cids > 1
) s on s.accountid = t.accountid;
+-----------+------+
| accountid | cid |
+-----------+------+
| 1 | 1 |
| 1 | 2 |
+-----------+------+
2 rows in set (0.00 sec)
You can use EXISTS :
SELECT lf.*
FROM LINKAGE_FILE lf
WHERE EXISTS (SELECT 1 FROM LINKAGE_FILE lf1 WHERE lf1.ACCOUNT_NUM = lf.ACCOUNT_NUM AND lf1.UNIQUE_CUSTOMER_ID <> lf.UNIQUE_CUSTOMER_ID);
However, you can also aggregation with your query :
SELECT ACCOUNT_NUM, COUNT(DISTINCT UNIQUE_CUSTOMER_ID)
FROM LINKAGE_FILE
GROUP BY ACCOUNT_NUM
HAVING COUNT(DISTINCT UNIQUE_CUSTOMER_ID) > 1;
By this, you can get only ACCOUNT_NUMs which have two or more CUSTOMER_IDs.

Select rows where subselect returns multiple values

I have two Tables [Users] and [Teams]. My Users Table looks like this [ID][E-Mail]. My Teams Table looks like this [Team][UserID].
I need to do a Subselect like this:
SELECT * FROM users WHERE 'ID' != (SELECT UserID FROM teams)
The Problem is that the Subselect returns multiple values. So i cannot compare it like this.
What i want to achive:
I want the Data from the User who IS NOT listed in the Table [Teams].
Example:
Table [Users] | Table[Teams] |
-------------- ------------------
[ID] [E-Mail] [UserID] [Team]
1 example1#google.com | 1 Football
2 example2#google.com | 1 Basketball
3 example3#google.com | 2 Basketball
So as you can see there are 3 exisiting Users, but the third User is not listed in the Table[Teams]. I want the E-Mail from the User, because he is not in any of these teams.
How could i accomplish that?
Instead of != use NOT IN:
SELECT * FROM users WHERE ID NOT IN (SELECT UserID FROM teams WHERE UserID IS NOT NULL)
Notice the UserID IS NOT NULL in sub query... NOT IN would fail if sub query returns one or more NULL values.
you can have multiple ways to implement the same
the below is one of the way
SELECT *
FROM users
WHERE ID NOT IN (SELECT UserID FROM teams)
We could also use an EXISTS clause:
SELECT *
FROM users u
WHERE NOT EXISTS (SELECT 1 FROM teams t WHERE u.ID = t.UserID);

Adding one extra row to the result of MySQL select query

I have a MySQL table like this
id Name count
1 ABC 1
2 CDF 3
3 FGH 4
using simply select query I get the values as
1 ABC 1
2 CDF 3
3 FGH 4
How I can get the result like this
1 ABC 1
2 CDF 3
3 FGH 4
4 NULL 0
You can see Last row. When Records are finished an extra row in this format
last_id+1, Null ,0 should be added. You can see above. Even I have no such row in my original table. There may be N rows not fixed 3,4
The answer is very simple
select (select max(id) from mytable)+1 as id, NULL as Name, 0 as count union all select id,Name,count from mytable;
This looks a little messy but it should work.
SELECT a.id, b.name, coalesce(b.`count`) as `count`
FROM
(
SELECT 1 as ID
UNION
SELECT 2 as ID
UNION
SELECT 3 as ID
UNION
SELECT 4 as ID
) a LEFT JOIN table1 b
ON a.id = b.id
WHERE a.ID IN (1,2,3,4)
UPDATE 1
You could simply generate a table that have 1 column preferably with name (ID) that has records maybe up 10,000 or more. Then you could simply join it with your table that has the original record. For Example, assuming that you have a table named DummyRecord with 1 column and has 10,000 rows on it
SELECT a.id, b.name, coalesce(b.`count`) as `count`
FROM DummyRecord a LEFT JOIN table1 b
ON a.id = b.id
WHERE a.ID >= 1 AND
a.ID <= 4
that's it. Or if you want to have from 10 to 100, then you could use this condition
...
WHERE a.ID >= 10 AND
a.ID <= 100
To clarify this is how one can append an extra row to the result set
select * from table union select 123 as id,'abc' as name
results
id | name
------------
*** | ***
*** | ***
123 | abc
Simply use mysql ROLLUP.
SELECT * FROM your_table
GROUP BY Name WITH ROLLUP;
select
x.id,
t.name,
ifnull(t.count, 0) as count
from
(SELECT 1 AS id
-- Part of the query below, you will need to generate dynamically,
-- just as you would otherwise need to generate 'in (1,2,3,4)'
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
) x
LEFT JOIN YourTable t
ON t.id = x.id
If the id does not exist in the table you're selecting from, you'll need to LEFT JOIN against a list of every id you want returned - this way, it will return the null values for ones that don't exist and the true values for those that do.
I would suggest creating a numbers table that is a single-columned table filled with numbers:
CREATE TABLE `numbers` (
id int(11) unsigned NOT NULL
);
And then inserting a large amount of numbers, starting at 1 and going up to what you think the highest id you'll ever see plus a thousand or so. Maybe go from 1 to 1000000 to be on the safe side. Regardless, you just need to make sure it's more-than-high enough to cover any possible id you'll run into.
After that, your query can look like:
SELECT n.id, a.*
FROM
`numbers` n
LEFT JOIN table t
ON t.id = n.id
WHERE n.id IN (1,2,3,4);
This solution will allow for a dynamically growing list of ids without the need for a sub-query with a list of unions; though, the other solutions provided will equally work for a small known list too (and could also be dynamically generated).

return null row in mysql if record not found for the given id

Hi am using the below mysql query
SELECT *
FROM particulars pp
WHERE (pp.SnoFK IN (108,999999)
AND pp.curMonth = STR_TO_DATE('01/02/2012', '%d/%m/%Y'))
In my table i have record for only 108, so it returns only one row for 108.
Is there any other option in mysql that can i return two rows which i dont have the id in the table like
1.108 | *
2.999999 | null values
I have no better idea:
http://sqlfiddle.com/#!2/82cc5/2
SELECT
ids.id,
particulars.*
FROM ( SELECT 108 AS id
UNION SELECT 1122 AS id
UNION SELECT 999999 AS id
) AS ids -- create a "table" with the required numbers
LEFT JOIN particulars ON particulars.SnoFK = ids.id

MySQL - Matching 2 rows (or more!) within a sub-query/table

I have this schema which I need to match 2 rows from
user_data : user_id, field_id, value
A sample output would be:
user_id field_id value
-----------------------------
1 1 Gandalf
1 2 Glamdring
How do I write a query which basically say "Find the user id of the user whose field_id 1 is Gandalf, and field_id 2 is Glamdring?"
SELECT FROM looks at one row at a time. I am stumped on this. I will also need to find a solution that scale gracefully (such as looking at three rows etc.)
You could run a query to get the users that match each of the conditions and intersect the results. Since MySQL doesn't support intersect you can do it with an n-way join:
SELECT T1.user_id
FROM Table1 T1
JOIN Table1 T2 ON T1.user_id = T2.user_id
WHERE T1.field_id = 1 AND T1.value = 'Gandalf'
AND T2.field_id = 2 AND T2.value = 'Glamdring'
I would try the following:
SELECT user_id
FROM user_data
WHERE ( field_id = 1 AND value= 'Gandalf' )
OR ( field_id = 3 AND value = 'Glamdring' )
GROUP BY user_id
HAVING COUNT( field_id ) = 2
It will search for all the rows that match one of your criteria, and use GROUP BY and HAVING afterwards to find the user_id that has the expected count of matches.
select * from user_date where ( field_id= 1 AND value='Gandalf' ) OR ( field_id =2 AND value ='Glamdring' ) ;
The HAVING clause is the key. It turns the query from an "OR" statement into an "AND" statement