0

I need to do a MYSQL query to select users from "table_in" which has the same format as table_1

 table_1
 id  Field_id  user_id  value
 1      9        1     "hello"
 2      10       1     "Multi"
 3      9        2     "Something"
 4      10       2     "Single"

 table_2
 id  user_id  status        specs
 1      1     "Busy"       "this is a test"
 2      2     "Idle"       "this is another test"
 3      2     "Busy"       "another test again"
 4      1     "Relaxing"   "something else"

I need to select users from table_in, where either one of the following is true

  1. table_1 field_id=10 contains "Multi"
  2. table_2 status is NOT Busy

Then save the result in a new table table_out

So what i got so far is this

  CREATE TEMPORARY TABLE table_out
    SELECT * FROM table_1 WHERE user_id in (SELECT user_id from table_in) 
    AND (field_id=10 AND value='Multi')
    OR (SELECT * from table_2 where status!='Busy')

Im not SQL expert and the MY-SQL statement i have above dont work. I think maybe the last OR statement is wrong where its trying to select from table_2 where the status is not busy.

So basically the users that gets put into table_out must all come from "table_in" and either have (field 10 set to multi), or the same user in table_2 (status!=Busy)

Does anybody know how to do it?

UPDATE: Found my own solution. Using table_in, create a second table by selecting only those values from it that is not "multi", then from that query table_2 for those user_id that are not busy put that in another table, then remove those values from table_in.

Thanks anyway

Paul Patt
  • 3
  • 5
  • So, is there actually 3 tables here? `table_in`, `table_1` and `table_2`? – SS_DBA Feb 20 '18 at 20:27
  • yes, table_in contains the actual users, then from those users you look in table_1 and table_2 to see if the information there corresponding to the users in table_in contains field 10=multi or the same user has table_2 status not busy. So you can only user the user_ids in table_in – Paul Patt Feb 20 '18 at 20:29
  • So if a user from table_in has any entry that is "busy" in table_2 you cant select them. So the users from table_in must either have "multi" in field_id=10, or "not busy" in status in table_2 – Paul Patt Feb 20 '18 at 20:33

4 Answers4

1

You could try it with a union statement. I do not have any mysql database here to test it, but it should kind of look like that

-- since table_in is a temporary table, we need to copy it first.
CREATE TEMPORARY TABLE table_in2 SELECT * FROM table_in;

CREATE TEMPORARY TABLE table_out SELECT table_out_alias.*
                             FROM (
                                    SELECT
                                      user_id AS user_id,
                                      value   AS value,
                                      ''      AS specs
                                    FROM table_1
                                    WHERE user_id IN (SELECT user_id
                                                      FROM table_in)
                                          AND (field_id = 10 AND value = 'Multi')
                                    UNION ALL
                                    SELECT
                                      user_id AS user_id,
                                      ''      AS value,
                                      specs   AS specs
                                    FROM table_2
                                    WHERE status != 'Busy' AND user_id IN (SELECT user_id
                                                                           FROM table_in2)
                                  ) AS table_out_alias

if i got your question right :)

djnose
  • 917
  • 7
  • 19
  • just wondering why you have the single quotes in there on the second line after value, and the last line after user_id? Thanks! – Paul Patt Feb 20 '18 at 21:07
  • it gave an error: cant reopen table_in on the last line – Paul Patt Feb 20 '18 at 21:34
  • Instead of the subquery, use an `Inner JOIN` to `table_in` for each `Select` statement. That might resolve your error. – SS_DBA Feb 20 '18 at 21:52
  • Can you please post the whole code since i dont know how to join yet – Paul Patt Feb 20 '18 at 21:54
  • are you only using temporary tables? The quotes in my query are used to create the same result, see the reply from tdjprog. **Each SELECT statement within UNION must have the same number of columns** – djnose Feb 20 '18 at 21:55
  • one answer here included an inner join, but gave same error – Paul Patt Feb 20 '18 at 21:56
  • table_1 and table_2 are not temporary, but table_in and table_out are temporary tables, and it gave cant reopen error on table_in – Paul Patt Feb 20 '18 at 21:59
  • okay, then you need to copy table_in before my statement and change the second line. More info: see https://stackoverflow.com/questions/343402/getting-around-mysql-cant-reopen-table-error. I will update my answer. – djnose Feb 20 '18 at 22:00
  • thanks for the update. now it gives error: every derived table must have its own alias – Paul Patt Feb 20 '18 at 22:06
  • I fixed that by adding "as tbl" on the last line, now it gives another error : "The used SELECT statements have a different number of columns ". isn't SQL a pain in the ass? – Paul Patt Feb 20 '18 at 22:26
  • i tried it now :) that answer should work now! :). Yeah, it can be :-) haven´t used it for a while .. getting old :D – djnose Feb 20 '18 at 22:31
  • Ok there is no more error, thanks, but what happens now is that it only selects users form table_2. If a user is in table_in, but not in table_2 that user is not selected. users in table_in should get selected by default even if they are not in table_2 – Paul Patt Feb 20 '18 at 22:50
0

From what I'm seeing... maybe something like this would work... Granted, I'm SQL Server, but I think this would work in MySQL.

Select t1.*
From Table_in TIN
JOIN Table_1 T1 ON TIN.User_ID = T1.User_ID
JOIN Table_2 T2 ON TIN.User_ID = T2.User_ID
Where (T1.Field_ID = 10 AND T1.Value = 'Multi')
OR (T2.Status != 'Busy')
SS_DBA
  • 2,403
  • 1
  • 11
  • 15
  • What does SELECT t1.* do?? – Paul Patt Feb 20 '18 at 20:52
  • Only selects the columns from `Table_1` aliased as `T1` – SS_DBA Feb 20 '18 at 20:52
  • ok thanks so much, it takes a long time to check it since i have to upload it to a server and then integrate it with other code in an SQL procedure – Paul Patt Feb 20 '18 at 20:58
  • is T1 aliased twice? on the first line and then again on the third? im new to sql sorry to ask – Paul Patt Feb 20 '18 at 21:05
  • The problem now is that it only selects users that are in table_2. If the user isnt in table 2 then they are not selected. If the user isnt in table_2 they should get selected altumatically – Paul Patt Feb 20 '18 at 21:39
  • This won't work then due to the `INNER JOIN`. I think the `UNION` approach might fit you better. Sorry. If you change them to `LEFT JOIN` I think that would make it worse and more confusing. – SS_DBA Feb 20 '18 at 21:46
  • ok, thanks good try, but the union approach gives an error: cant re-open table_in – Paul Patt Feb 20 '18 at 21:50
0

You must use UNION ALL operator.

The UNION operator is used to combine the result-set of two or more SELECT statements.

  • Each SELECT statement within UNION must have the same number of columns
  • The columns must also have similar data types

  • The columns in each SELECT statement must also be in the same order.

    CREATE TEMPORARY TABLE table_out
    SELECT * FROM table_1 WHERE user_id in (SELECT user_id from table_in) AND (field_id=10 AND value='Multi')
    

The UNION operator selects only distinct values by default. To allow duplicate values, use UNION ALL

UNION ALL
    SELECT t2.id, t_in.field_id, t2.user_id, t_in.value
    FROM table_2 AS t2
    INNER JOIN table_in AS t_in
    ON t2.user_id = t_in.user_id
    WHERE t2.status != 'Busy';
tdjprog
  • 706
  • 6
  • 11
0

I think you'll find this does what you're looking for:

SELECT *
  FROM table_in ti
  INNER JOIN table_1 t1
    ON t1.user_id = ti.user_id
  LEFT OUTER JOIN table_2 t2
    ON t2.USER_ID = ti.USER_ID
  WHERE (t1.field_id = 10 AND t1.value = 'Multi') OR
        t2.status <> 'Busy'

To have this work as intended table_2 should be an outer (optional) join. Actually, as I don't have a complete grasp on the problem it may well be that BOTH table_1 and table_2 should be outer joins. Well, it's something further for you to play with.

I had to make some assumptions, which I encapsulated in this SQLFiddle. Note that in the fiddle I only populated table_in with a user_id of 1, just to test it out. Change it around as needed to test further.

Best of luck.

EDIT

The code from the fiddle is:

create table table_in(user_id int);

insert into table_in(user_id) values (1);



create table table_1(id int, field_id int, user_id int, value varchar(20));

 insert into table_1 (id,  Field_id,  user_id,  value) values (1,      9 ,       1,     'hello');
 insert into table_1 (id,  Field_id,  user_id,  value) values (2,      10,       1,     'Multi');
 insert into table_1 (id,  Field_id,  user_id,  value) values (3,      9 ,       2,     'Something');
 insert into table_1 (id,  Field_id,  user_id,  value) values (4,      10,       2,     'Single');

 create table table_2 (id int, user_id int, status varchar(10), specs varchar(25));

insert into table_2(id,  user_id,  status, specs) value (1,      1,     'Busy'     ,  'this is a test');
insert into table_2(id,  user_id,  status, specs) value ( 2,      2,     'Idle'     ,  'this is another test');
insert into table_2(id,  user_id,  status, specs) value ( 3,      2,     'Busy'     ,  'another test again');
insert into table_2(id,  user_id,  status, specs) value ( 4,      1,     'Relaxing' ,  'something else');

Putting it here because SQLFiddle seems to be going on and off line like a ping-pong ball today. :-(