Add attribute as column if second table contains record - mysql

I have two databases: one contains the users:
persons
id
name
course
the other one contains the
voters
id
personID
type
An entry to the voters table gets added when the user voted (type describes different topics a user can vote on)
I want to get all users for example where persons.course = '1' AND voters.type = '2' and have the output contain the following columns: id, name, hasVoted (where hasVoted returns true if the personID can be found in the voters table)

A left join may be what your looking for.
SELECT persons.id, persons.name, voters.personID IS NOT NULL AS hasVoted
FROM persons LEFT JOIN voters ON (persons.id = voters.personID)
WHERE persons.course = '1' AND voters.type = '2'
GROUP BY persons.id
http://dev.mysql.com/doc/refman/5.0/en/join.html
The left join will include all the matching rows from the left side of the join, and any matching pieces from the right side of the join. Any rows from the left side without a matching right side will be have the right side columns values of null.
As for the 'IS NOT NULL' or 'IS NULL' is used because 'X = NULL' doesn't behave as it appears.
> SELECT 'A' = NULL, 'A' IS NULL, NULL = NULL, NULL IS NULL;
+------------+-------------+-------------+--------------+
| 'A' = NULL | 'A' IS NULL | NULL = NULL | NULL IS NULL |
+------------+-------------+-------------+--------------+
| NULL | 0 | NULL | 1 |
+------------+-------------+-------------+--------------+
More details about working with nulls:
http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html

Related

SQL-Query - Join multiple tables with additional dynamic column

I need help for building a SQL-statement. The Database-Schema looks like this:
I did prepare the following SQL-Fiddle, which contains sample-data:
http://sqlfiddle.com/#!9/831bab/1
As for the sample-data in the SQL-Fiddle, I want to query for the computername "Client02" and want to get the following result:
Wanted result 1
PrinterName | PrintServer | PrinterActive | ComputerActive | isDefaultPrinter
PRT01_Zentral | DC01 | True | True | False
PRT02_BH | DC01 | True | True | True
As for the sample-data in the SQL-Fiddle, I want to query for the computername "Client01" and want to get the following result:
Wanted result 2
PrinterName | PrintServer | PrinterActive | ComputerActive | isDefaultPrinter
PRT01_Zentral | DC01 | True | True | True
As you see, I need to join all the tables and add something like a helper-column, which contains information about the default-printer. (True/False)
I started to build up the query, but I don't know how to proceed ...
SELECT printers.PrinterName, printers.PrintServer, printers.PrinterActive
FROM computermapping
LEFT JOIN computers ON computermapping.ComputerID = computers.ComputerID
LEFT JOIN printers ON computermapping.PrinterID = printers.PrinterID
LEFT JOIN computerdefaultprinter ON computers.ComputerID = computerdefaultprinter.ComputerID
WHERE computers.ComputerName = "Client02"
I think my request contains all the information, which is needed. The SQL-Fiddle has sample-data to easily reproduce it. The WantedResults should show the target clearly.
EDIT:
DBMS: MySQL
You could use the following query to get the result that you need
SELECT printers.PrinterName,
printers.PrintServer,
printers.PrinterActive,
computers.ComputerActive,
CASE
WHEN computerdefaultprinter.PrinterID IS NULL THEN "false"
ELSE "true"
END AS isDefaultPrinter
FROM computermapping
LEFT JOIN computers
ON computermapping.ComputerID = computers.ComputerID
LEFT JOIN printers
ON computermapping.PrinterID = printers.PrinterID
LEFT JOIN computerdefaultprinter
ON computers.ComputerID = computerdefaultprinter.ComputerID
AND printers.PrinterID = computerdefaultprinter.PrinterID
WHERE computers.ComputerName = "Client02"
I've only added CASE...WHEN statement and modified join condition of your original query.
But I think instead of using table computerdefaultprinter, why don't you add column IsDefaultPrinter to table computermapping.
CREATE TABLE `computermapping` (
`ComputerMappingID` int(11) NOT NULL,
`PrinterID` int(11) NOT NULL,
`ComputerID` int(11) NOT NULL,
`IsDefaultPrinter` int(1) NOT NULL DEFAULT 0,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
What I did was add a if statement in your query, comparing the inner result (that can only be 1) to your outter select. There is a better way of achieving this probably but this answer reflects the queryresult's that you've asked.
Edit: I'm assuming only a default printer per computer.
Are you sure the wanted result 2 is correct? Because in the database, records are saying computer1 has 1 printerid (1) that is the default and that computer2 has 2 printers (1 and 2) and 2 is default.
SELECT printers.PrinterName,
printers.PrintServer,
printers.PrinterActive,
IF (
(SELECT computerdefaultprinter.printerid
FROM computerdefaultprinter
WHERE computerdefaultprinter.computerid = computermapping.computerid) = computermapping.printerid,
'true',
'false') AS isDefaultPrinter
FROM computermapping
LEFT JOIN computers ON computermapping.ComputerID = computers.ComputerID
LEFT JOIN printers ON computermapping.PrinterID = printers.PrinterID
LEFT JOIN computerdefaultprinter ON computers.ComputerID = computerdefaultprinter.ComputerID
WHERE computers.ComputerName = "Client02"

RIGHT JOIN is returning all NULL results

I have two tables:
I'm trying to retrieve fields name, quantity and custom_message from table 1 and join the correct associated field value from table 2 - to give me:
name | quantity | custom_message | value
This is my query:
SELECT vxu_4_wpsc_cart_contents.name, vxu_4_wpsc_cart_contents.quantity,
vxu_4_wpsc_cart_contents.custom_message
FROM vxu_4_wpsc_cart_contents
RIGHT JOIN vxu_4_wpsc_submited_form_data
ON vxu_4_wpsc_cart_contents.id = vxu_4_wpsc_submited_form_data.id
WHERE form_id =2
OR form_id =3
which is returning
name | quantity | custom_message
NULL NULL NULL
NULL NULL NULL + 3 more rows of nulls
vxu_4_wpsc_cart_contents:
table 1
vxu_4_wpsc_submited_form_data:
I just don't know where I'm going wrong!
I believe right join should be inner join. Try the following query:
SELECT
vcc.name,
vcc.quantity,
vcc.custom_message,
vfd.value
FROM
vxu_4_wpsc_cart_contents AS vcc
INNER JOIN vxu_4_wpsc_submited_form_data as vfd
ON vcc.purchaseid = vfd.log_id
WHERE
vfd.form_id IN (2,3);
(fyi: your second image link is the same as the first :))

Conditionally select from one table or another in MySQL

In MySQL, how do I select from another table if a foreign key is set?
What I'm trying to do is select Fields.value if Fields.value_id isn't set, otherwise select Values.value from Values where Value.id is equal to Fields.value_id.
My tables:
Fields:
id | value | value_id
Values:
id | value
What's wrong with my code here?
Code:
SELECT CASE
WHEN Field.value_id = NULL OR Field.value_id = ""
THEN Field.value
ELSE
Value.value
FROM values as Value
WHERE (Field.value_id = Value.id)
One syntax error is that you are missing the end in the case. I also think you want a left join between the tables. My best guess given the available information is this:
SELECT (CASE WHEN f.value_id = NULL OR f.value_id = ''
THEN f.value
ELSE v.value
END)
FROM fields f left join
values v
on f.value_id = v.id;

LEFT OUTER JOIN with four table

Here is the table structure
User table
Column
fb_id
email
name
fname
lname
gender
fb_link
created
referral table
Column
id
referred_by
joinee
created
Currently implemented one SQL is (Example 1)
SELECT u.fb_id
,fb_link
,name
,r.referred_by
,u.created
FROM users u
LEFT OUTER JOIN referral r
ON u.fb_id=r.joinee
result of above query
joinee referer
10152250261037651 NULL
10152604594389921 NULL
10154430845000507 1518673071699780
....
....
....
....
547146735389782 NULL
Here is the sql (Example 2)
SELECT u_joinee.fb_id joinee_fb_id
,u_referer.fb_id referer_fb_id
,u_joinee.NAME joinee_name
,u_referer.NAME referer_name
FROM users u_joinee
,users u_referer
,referral r_j
,referral r_r
WHERE u_referer.fb_id = r_r.referred_by
AND u_joinee.fb_id = r_j.joinee
result of above query
joinee_fb_id referer_fb_id joinee_name referer_name
10154430845000507 1518673071699780 Saselsdein Bsdasd
What I am looking out for is I need both name in joinee_name and referer_name in the output. But I ma not able to use four tables in LEFT OUTER JOIN clause like i did for example 1 I want to fetch both records which include both non referral and referral joinees Is there any way to expect required result as shown below
Expected result
joinee_fb_id referer_fb_id joinee_name referer_name
10154430845000507 1518673071699780 Saselsdein Bsdasd
10154430845000347 Null asd NULL
10154430845000567 Null asd asdm NULL
10154230845000567 Null Dsd asdm NULL
10154330845000567 Null sdm NULL
101544553045000567 Null Esd aedm NULL
You can join with the users table twice by giving it different aliases, just like you do with your implicit inner join.
I don't think you need to join with referral twice. A single row in the referral table links a referrer and a joinee.
SELECT u_joinee.fb_id joinee_fb_id ,u_referer.fb_id referer_fb_id, u_joinee.name joinee_name, u_referer.name referer_name
FROM users AS u_joinee
LEFT JOIN referral AS r ON r.joinee = u_joinee.fb_id
LEFT JOIN users AS u_referer ON r.referred_by = u_referer.fb_id

MySQL LEFT OUTER JOIN not filtering records

I am trying a simple LEFT JOIN query where I want the records from the LEFT table where there
are no matches in the RIGHT table.
SELECT
LeftTable.ID,
RightTable.ID as NullID
FROM
LeftTable
LEFT OUTER JOIN RightTable ON RightTable.ID = LeftTable.ID
So, how do I select the rows where the result only contains records where NullID is NULL?
I thought an LEFT OUTER JOIN was what was required but all the Left records are being returned with matching and unmatching right records where I only want left records with unmatching right records.
The database engine is InnoDB.
For example, the query is returning the following:
LeftTable.ID, NullID
1, 1
2, Null
I only want result 2 i.e. where NullID = Null
I tried the following LEFT JOIN and is the kind of query I have been trying but I get the error
"[Err] 1054 - Unknown column 'NullID' in 'where clause'".
SELECT
LeftTable.ID,
RightTable.ID as NullID
FROM
LeftTable
LEFT JOIN RightTable ON RightTable.ID = LeftTable.ID
where NullID = Null;
Hopefully this explains my problem. Thanks.
As documented under Working with NULL Values:
To test for NULL, use the IS NULL and IS NOT NULL operators, as shown here:
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
| 0 | 1 |
+-----------+---------------+
You cannot use arithmetic comparison operators such as =, <, or <> to test for NULL. To demonstrate this for yourself, try the following query:
mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
| NULL | NULL | NULL | NULL |
+----------+-----------+----------+----------+
Because the result of any arithmetic comparison with NULL is also NULL, you cannot obtain any meaningful results from such comparisons.
Also, as documented under Problems with Column Aliases:
Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined.
Therefore, in your case:
SELECT LeftTable.ID, RightTable.ID as NullID
FROM LeftTable LEFT JOIN RightTable ON RightTable.ID = LeftTable.ID
WHERE RightTable.ID IS NULL
You can try this:
SELECT
LeftTable.ID,
RightTable.ID as NullID
FROM
LeftTable
LEFT JOIN RightTable ON RightTable.ID = LeftTable.ID
where RightTable.NullID IS NULL;