(Mysql) How to mark different WHERE OR rows? - sql

For example i have requested:
WHERE (friend_id=? OR client_id=?)
How do i know which row meets friend_id condition and which meets client_id condition?
Is it possible to mark/flag rows depending of meeting condition somehow?
Thanks.

SELECT friend_id=? FROM yourtable WHERE (friend_id=? OR client_id=?);
You will get a true if the friend_id clause matches:
Or even:
SELECT friend_id=?, client_id=? FROM yourtable WHERE (friend_id=? OR client_id=?);
To get both matches. In this way you can see if one or both matches.

Use CASE operator
If knowing which row was hit because by any condition you can of course add this data to your result columns using case operators. The only downside is that your variables in your prepared statement (if that's what you're having here) are going to be doubled.

You can use UNION.
For example:
SELECT name, 1
FROM friends
WHERE friend_id=?
UNION
SELECT name, 0
FROM friends
WHERE client_id=?
Then when receiving data, you can check for that flag

SELECT *,
'Friend' AS Source
FROM TABLE
WHERE friend_id = ?
UNION
SELECT *,
'Client' AS Source
FROM TABLE
WHERE client_id = ?
But you'll have an issue if your entry is both friend and client. What do you want to happen in this case?

You can use IF(), but then you have to bind one of id twice:
SELECT IF(friend_id=?, 'friend', 'client') AS type
FROM table
WHERE (friend_id=? OR client_id=?)

you can add flags to the query:
SELECT *, IF((friend_id=$friend_id), 1, 0) AS friend_matched, IF((client_id=$client_id), 1, 0) AS client_matched FROM table WHERE (friend_id=? OR client_id=?)

Related

SQL ManyToOne condition

But if I add one more for my query (that not related to this), for example:
I should get nothing
(but it needs to be workable :D)
You can do a GROUP BY, and use HAVING to make sure all desired tag_id's are there:
SELECT sp.perfume_id
FROM sp_tag_to_perfume sp
WHERE sp.tag_id IN (2070, 127)
GROUP BY sp.perfume_id
HAVING COUNT(DISTINCT sp.tag_id) = 2; -- number of tag_id values (in this case 2070 and 127)
This can get all the columns and data containing perfume id 199.
Select * from sp_tag_to_perfume sp where sp.perfume_id=199;
And from tag_id...
Select distinct perfume_id from sp_tag_to_perfume sp where sp.tags_id=127;
You can use distinct keyword to get unique values of the column.

I need to SELECT a group of columns not null

Basically, i have a table that have a series of columns named:
ATTRIBUTE10, ATTRIBUTE11, ATTRIBUTE12 ... ATTRIBUTE50
I want a query that gives me all the columns from ATTRIBUTE10 to ATTRIBUTE50 not null
As others have commented we aren't exactly sure of your requirements, but if you want a list the UNPIVOT can do that...
SELECT attribute , value
FROM
(SELECT * from YourFile) p
UNPIVOT
(value FOR attribute IN
(attribute1, attribute2, attribute3, etc.)
)AS unpvt
May be you can use where condition for all columns Or use between operator as below.
For All Columns
where ATTRIBUTE10 is not null and ATTRIBUTE11 is not null ...... and ATTRIBUTE50 is not null
By using between operator
where ATTRIBUTE10 between ATTRIBUTE11 and ATTRIBUTE50
One way to approach the problem is to unfold your table-with-a-zillion-like-named-attributes into one in which you've got one attribute per row, with appropriate foreign keys back to the original table. So something like:
CREATE TABLE ATTR_TABLE AS
SELECT ID_ATTR, ID_TABLE_WITH_ATTRS, ATTR
FROM (SELECT ((ID_TABLE_WITH_ATTRS-1)*100)+1 AS ID_ATTR, ID_TABLE_WITH_ATTRS, ATTRIBUTE10 AS ATTR FROM TABLE_WITH_ATTRS UNION ALL
SELECT ((ID_TABLE_WITH_ATTRS-1)*100)+2, ID_TABLE_WITH_ATTRS, ATTRIBUTE11 FROM TABLE_WITH_ATTRS UNION ALL
SELECT ((ID_TABLE_WITH_ATTRS-1)*100)+3, ID_TABLE_WITH_ATTRS, ATTRIBUTE12 FROM TABLE_WITH_ATTRS);
This only unfolds ATTRIBUTE10, ATTRIBUTE11, and ATTRIBUTE12, but you should be able to get the idea - the rest of the attributes just requires a little cut-n-paste on your part.
You can then query this table to find your non-NULL attributes as
SELECT *
FROM ATTR_TABLE
WHERE ATTR IS NOT NULL
ORDER BY ID_ATTR
Hopefully the difficulty you're encountering in dealing with this table-with-a-zillion-repeated-fields teaches you a hard lesson about exactly why tables with repeated fields or groups of fields are a Bad Idea.
dbfiddle here

How do I combine columns into one, and filter out NULLs?

Here is my table. A list of ids with signup dates in columns newsletter, report, infographics.
I want to combine all those columns into one, without the NULLs
I've tried the following code
SELECT id, combined_column
FROM (
SELECT id, CONCAT(newsletter, report, infographics) AS combined_column
FROM table
)
WHERE combined_column IS NOT NULL
But this just gives me a blank table. Is there a way to solve this? Thanks
I think you want coalesce which return the first not null value from the list (it you have more than one not null value in a row it'll still return the first one):
SELECT id, COALESCE(newsletter, report, infographics) AS combined_date
FROM t
WHERE COALESCE(newsletter, report, infographics) IS NOT NULL
Do you just want this?
select max(newsletter) as newsletter,
max(report) as report,
max(infographics) as infographics
from t;
Answer may depend on what database you're using, so caveat lector.
Is it the case that only one column will be non-null, as in your sample?
Then something like:
SELECT id, COALESCE(newsletter, infographics, report) FROM my_table;
might work for you...
If you are using Oracle, use NVL to replace NULL with empty string
SELECT id,
combined_column
FROM (
SELECT id,
CONCAT(NVL(newsletter,''), NVL(report,''), NVL(infographics,'')) AS combined_column
FROM table
)
WHERE combined_column is not NULL
SELECT id,
CONCAT(newsletter, report, infographics) AS combined_column
FROM table WHERE newsletter is NOT NULL and report is NOT NULL and infographics is NOT NULL

How to give the output of the first query(which has two values) as the input to the second?

i get 2 names as the output of the first query....
eg: paul,peter
now this should be the input for the second query,
which has to display paul's and peter's email ids....
For nested queries I would strongly recommend WITH clause. It makes long complex queries order of magnitude easier to understand / construct / modify:
WITH
w_users AS( -- you can name it whatever you want
SELECT id
FROM users
WHERE < long condition here >
),
w_other_subquery AS(
...
)
SELECT email_id
FROM ...
WHERE user_id IN (SELECT id FROM w_users)
You can use like this
LIKE
SELECT USER_ID,EMAIL_ID FROM USERS where user_id IN
(SELECT PRODUCT_MEMBERS FROM PRODUCT WHERE PRODUCT_NAME='ICP/RAA');
Just use the IN clause '=' is used for matching one result
You can use In Command to get result
ex:
SELECT email FROM tableName WHERE (Name IN ('paul', 'peter'))

How do I select only 1 row in sybase without using rowcount

How do I select only 1 row in sybase without using rowcount? I don't have the privilege to set rowcount in sybase. Is there a way to select only 1 row?
For example:
select * from table where name = 'jack'
This returns two rows; how do I select only one row from the result set without using set rowcount?
Try the query:
SELECT TOP 1 * FROM mytable
WHERE name = 'jack'
As you might guess, this selects the TOP 1 matching results. If you wanted more (which you don't here) you could use any number (TOP 100 or TOP 1000, etc).
A more comprehensive example can be found on w3schools: http://www.w3schools.com/Sql/sql_top.asp
There seems to be a reason, why you're getting more than 1 row for "WHERE name = 'jack'", it looks as if the rows differ.
But if, the rows do not differ you can try adding "distinct":
SELECT DISTINCT * FROM TABLE WHERE name = 'jack'
or try with "GROUP BY" statement, then you should type explicitly all columns, eg.:
SELECT name FROM TABLE WHERE name = 'jack' GROUP BY name
if this is not what you wanted, can you paste here how the 2 rows look exactly?
If you want a single result, use 'GROUP BY' and 'HAVING column = max(column)'. Or replace max() with min().
This should work unless the max or min values are also not unique.