Condition with SQL - sql

I've come to see you for a question. Is there a condition in SQL that allows you to do that:
IF(sup = void) {
}
Database
id | name | lastname | city | mail | number | picture | ...
1 | kiwi | kiwi | USA | kiwi#gmail.com | 0000000000 | default.img | (vide)

SELECT * FROM your_table WHERE sup IS NULL
https://www.w3schools.com/sql/sql_null_values.asp
Update after reading your comment.
$test = $db->query("SELECT * FROM ressource_view WHERE ID = 1")
Will give you the result of your query. Be careful as there could be multiple rows returned.
To fetch the first row
$row = $result->fetch_array()
And then to check if the sup column of your row is null you can use:
if(is_null($row['sup']))
{
}
Or this will have the same effect
if($row['sup'] === NULL)
{
}
But best to tag your question with PHP, MySQL. Your problem seems to be more on the PHP side and someone else could provide a better answer.

Related

How to get column names from a query?

I have a specific query with joins and aliases, and I need to retrieve columns name for a REST request in Talend.
I'm using Talend Open Studio for Data Integration 6.2 and I've got an Oracle 11g database with a read-only account. I can execute scripts with Talend, For example the query:
select
u.name as "user",
f.name as "food",
e.rate
from
Users as u
join Eval as e on u.user_id = e.user_id
join Food as f on e.food_id = f.food_id
where
1 = 1
should give the following result:
+------+--------+------+
| user | food | rate |
+------+--------+------+
| Baba | Donuts | 16.0 |
| Baba | Cheese | 20.0 |
| Keke | Pasta | 12.5 |
| Keke | Cheese | 15.0 |
+------+--------+------+
And I try to get the columns (in the right order) as follows by using scripts or Talend:
+--------+
| Column |
+--------+
| user |
| food |
| rate |
+--------+
Is there a way to query the Oracle database to get the columns or using talend to retrieve them?
UPDATE
Thanks to Marmite Bomber, a duplicate has been identified here for the Oracle approach. Now we need a Talend approach to the problem.
You can try this on a tJavaRow, following your DBInput component :
for (java.lang.reflect.Field field: row1.getClass().getDeclaredFields()) {
context.columnName = field.getName();
System.out.println("Field name is " + context.columnName );
}
Spotted on talend help center here : https://community.talend.com/t5/Design-and-Development/resolved-how-to-get-the-column-names-in-a-data-flow/td-p/99172
You can extend this, and put the column list on your outputflow :
//add this inside the loop, and 'columnNames' as an output row in tJavaRow schema
output_row.columnNames+=context.columnName+";";
With a tNormalize after tJavaRow, you shoud get the expected result.
Here´s a link to an oracle community thread which should answer your question
community.oracle.com
I am not able to write a comment, so posting this as an answer:
SELECT column_name
FROM all_tab_cols
WHERE table_name = 'table_name_here'

Is there a conditional where statement in SQLite?

I have a Todo application with a database for the todos. It contains a column done which will be set to false or true. Now I want to filter the data by all or unfinished. So either done is irrelevant or it has to be false.
I am using SQLite3 in a TypeScript application. Currently I do this by using string templates but I'd prefer an SQL-based solution.
db.prepare(`
select
rowid as id,
title,
description
from todo
${selectAll ? '' : 'where done = 0'}
limit ?
offset ?
`).all(limit, offset);
My idea was to use the CASE clause but it seems not to work around the WHERE clause.
Is there any better solution?
selectAll is a TypeScript variable that is set depending on the query parameters of the app.
Output when selectAll is false
id | title | description | done
1 | Clean the kitchen | as the title says... | 1
2 | Do the shopping | potatoes, tomatoes | 0
3 | Program stuff | Todo app | 1
Output when selectAll is true
id | title | description | done
2 | Do the shopping | potatoes, tomatoes | 0
You can use boolean logic:
where ? = '' or done = 0

tell me the sql

I have a table like this.
Table name : message
mid | mfrom | mto | msg
------------------------
1 | a | b | hi
2 | b | a | hello
3 | a | c | how are you
4 | c | a | fine
i am able to show all rows by
`$sql = mysql_query("SELECT *
FROM message
WHERE mto = '$to'
OR mfrom = '$to';");
while($row = mysql_fetch_array($sql))
{
echo $row['msg'];
}`
but i want to show only one result if mfrom and mto or mto and mfrom is equal. Such as if mfrom =a and mto=b or mfrom=b and mto=a. I want to show only one result from them like this
mid | mfrom | mto | msg
-------------------------
2 | b | a | hello
4 | c | a | fine
please tell me the query.
Your question is not clear because your "query" seems wrong ("mfrom and mto or mto and mfrom is equal" doesn't seem correct).
Nevertheless, as you named the table "message", I'm guessing that you want each message once even though it appears twice in the table.
What you could do is query from the table "twice" and then use the bigger of the ids:
SELECT first.* FROM message AS first LEFT JOIN message AS second
ON first.mfrom = second.mto AND first.mto = second.mfrom
WHERE first.mid > second.mid OR second.mid is NULL;
This would give you the result you requested. It would also give you any message that doesn't have a "partner" row.
If you want only matching messages, you can remove the "OR second.mid is NULL".

Access SQL Max-Function

I have a question concerning MS Access queries involving these tables:
tblMIDProcessMain ={ Process_ID,Process_Title,...}
tblMIDProcessVersion = { ProcessVersion_ID, ProcessVersion_FK_Process, ProcessVersion_VersionNo, ProcessVersion_FK_Status, ...}
tblMIDProcessVersionStatus = { ProcessVersionStatus_ID,ProcessVersionStatus_Value }
The tables store different versions of a process description. The "ProcessVersion_VersionNo" field contains an integer providing the version number. Now I would like to get for each process the highest version number thus the current version. If I do the following it kind of works:
SELECT tblMIDProcessMain.Process_Titel
, Max(tblMIDProcessVersion.ProcessVersion_VersionNo) AS CurrentVersion
FROM tblMIDProcessMain
INNER JOIN tblMIDProcessVersion
ON tblMIDProcessMain.Process_ID = tblMIDProcessVersion.ProcessVersion_FK_Process
GROUP BY tblMIDProcessMain.Process_Titel;
The query returns a recordset with each existing process_title and the respective max number of the version field. But as soon as I add other fields like "ProcessVersion_FK_Status" in the Select statement the query stops working.
Any help would be appreciated. Thanks in advance.
Jon
Edit:
To clarify things a little I added a simplified example
Parent-Table:
Process_ID | Process_Title
----------------------------------
1 | "MyProcess"
2 | "YourProcess"
Child-Table:
Version_ID | Version_FK_ProcessID | Version_No | Version_Status
---------------------------------------------------------------------------
1 | 1 | 1 | "New"
2 | 2 | 1 | "Discarded"
3 | 2 | 2 | "Reviewed"
4 | 2 | 3 | "Released"
Intended Result:
Title | Max_Version_No | Status
--------------------------------------------------------
MyProcess | 1 | "New"
YourProcess | 3 | "Released"
Given the example tables you updated your post with, this should work:
select process_title as Title
, max_version.max_version_no
, c.version_status as status
from (parenttable p
inner join (select max(version_id) as max_version_no, version_fk_process_id from childtable group by version_fk_process_id) max_version
on p.process_id = max_version.version_fk_process_id)
inner join childtable c
on max_version.max_version_no = c.version_id and max_version.version_fk_process_id = c.version_fk_process_id
I assume you are adding the new field to the 'Group By" clause? If not, then you either must include in the 'Group By', or you must use one of the operators like "Max" or "First" etc.

connecting three tables in one query

I have the following tables
mixes
mid | date | info
1 | 2009-07-01 | no info yet
music-review
mid | song | buy
1 | Example - Example | http://example.com
2 | Exam - Exam | http://example.com
tracklist
tid | mid | mrid
1 | 1 | 1
2 | 1 | 2
is it possible to have an SQL query where you can link these all into one?
so my results would turn out like:
date | info | tracklist
2009-07-01 | no info yet | Example - Example http://example.com, Exam - Exam http://example.com
or however this result would be returned... or would this need to be a two sql querys where i get the MID from the mixes and then do a query to get the tracklist from that?
For MySQL:
SELECT mixes.date, mixes.info,
GROUP_CONCAT(DISTINCT music-review.song + ' ' + music-review.buy
ORDER BY music-review.mid ASC SEPARATOR ', ')
FROM mixes
JOIN tracklist ON tracklist.mid = mixes.mid
JOIN music-review ON music-review.mrid = tracklist.mrid
GROUP BY mixes.date, mixes.info
this works as adapted from mherren:
SELECT mixes.`date`, mixes.info,
CONCAT(GROUP_CONCAT(DISTINCT `music-review`.song , ' ' , `music-review`.`mid`
ORDER BY `tracklist`.`tid` ASC SEPARATOR ', ')) as `tracklist`
FROM mixes
JOIN tracklist ON tracklist.`mid` = mixes.`mid`
JOIN `music-review` ON tracklist.`mrid` = `music-review`.`mid`
WHERE `mixes`.`date`='2009-07-01'
GROUP BY mixes.`date`, mixes.info;
it fixes a blurb issue i was getting but, one thing is that group_concat has a max limit set at 1024 this can be altered tho by
SET GLOBAL group_concat_max_len=4096
I left so many comments, I thought it would be more helpful to suggest a revision to your architecture as an answer. However, I do think mherren has already competently addressed your actual concern, so while votes are appreciated, I don't think this should be considered as the the right "answer".
I think you need to reconsider how you have arranged the data. Specifically, you have a table for "music-review" that seems out of place while at the same time you refer to "mixes" and "tracklists" which seems a bit redundant. I imagine you want a one-to-many relationship where "mixes" refers to the information about the mix, like when it was created, the user who created it, etc. While "tracklist" is the list of songs within the "mix". What if you tried this:
#song-info
song_id | artist | title | online-store
1 | The Airheads | Asthma Attack! | example.com/?id=123
2 | The Boners | Bite the Boner | example.com/?id=456
3 | Cats in Heat | Catching a Cold | example.com/?id=789
4 | Dirty Djangos | Dig these Digits | example.com/?id=147
#mixes
mix_id | date | info
1 | 2009-07-01 | no info yet
2 | 2009-07-02 | no info yet
#mix_tracklist
mix_id | song_id
1 | 1
1 | 2
2 | 2
2 | 3
Now you can have a list of available mixes, and if a user selects a mix, another query for the actual songs.
Trying to put all of the song data into one column should only be done if the results require that info right away or if there is a condition within the query itself that is conditional to the results of that sub-query. If you simply want to output a list of mixes with the track list for each one, you are better of doing the query for each mix based on the mix index. So in the case of php outputting HTML, you would go with:
$mixes = mysql_query("SELECT * FROM mixes WHERE date > '$last_week'");
while($mix = mysql_fetch_assoc($mixes)) {
$mix_id = $mix['mix_id'];
$mix_date = date('m/d/Y', strtotime($mix['mix_id']));
$mix_info = $mix['mix_id'];
echo <<<EOT
<h2 class="mix_number">$mix_number</h2>
<p class="mix_date">$mix_date</p>
<p class="mix_info">$mix_info</p>
<h3>Track Listing:</h3>
<ul class="tracklist">
EOT;
$tracks = mysql_query("SELECT song.artist artist,
song.title title,
song.online-store url
song.song_id
FROM song-info song
JOIN mix_tracklist tracks ON (tracks.song_id = song.song_id)
WHERE tracks.mix_id = '$mix_id'
ORDER_BY song_id);
while ($track = mysql_fetch_assoc($tracks)) {
$artist = $track['artist'];
$song_name = $track['title'];
$song_url = $track['url'];
echo <<<EOT
<li>$artist – $song_name</li>
EOT;
}
echo "</ul>";
}