Select all except if specific cell value in MYSQL - mysql

I'm stuck and I can't figure it out, so I would appreciate any help.
At this point i have table journal which consists of columns:
id | name | type(int) | classification | data | journalUser | start_date(default NULL)
1 | John | 1 | 2 | data123 | 1 | 10-11-2019
2 | Peter | 2 | 2 | data123 | 1 | 10-11-2019
3 | Ash | 2 | 2 | data123 | NULL | NULL
4 | BUBU | 2 | 2 | data123 | 3 | 10-11-2019
I want to make query where I select all, but with exceptions, for example: SELECT * from journal, but if column type = 2, than select this row too if journalUser = 1 AND second check if column type = 2 and start_date IS NULL, than select this row too.
As the result, from table above, from query I wan to get result
id | name | type(int) | classification | data | journalUser | start_date(default NULL)
1 | John | 1 | 2 | data123 | 1 | 10-11-2019
2 | Peter | 2 | 2 | data123 | 1 | 10-11-2019
3 | Ash | 2 | 2 | data123 | NULL | NULL

That's a specific case when the type is 2.
To get the rows with type = 2 along with either (considering the expected output) journalUser = 1 or start_date = null, this can be written this way :
type = 2 AND (journalUser = 1 OR start_date IS NULL)
To make sure you have others type too, you can add an OR condition such as :
OR type <> 2.
This will give this query :
SELECT *
FROM journal
WHERE (type = 2 AND (journalUser = 1 OR start_date IS NULL))
OR type <> 2

Related

SQL newbie question - trying to set a value where two columns match and another column has another value

I'm trying to set the value of a column 'VALUE' where the 'ID' equals 2 AND the 'USERID' matches another row in the same table, where the 'ID' equals 1 and the VALUE is, say, 'London' in the example...
So:
ID | USERID | VALUE
1 | 1 | London
1 | 2 | Madrid
1 | 3 | London
1 | 4 | Paris
2 | 1 | null
2 | 2 | null
2 | 3 | null
2 | 4 | null
Becomes
ID | USERID | VALUE
1 | 1 | London
1 | 2 | Madrid
1 | 3 | London
1 | 4 | Paris
2 | 1 | on
2 | 2 | null
2 | 3 | on
2 | 4 | null
Is this possible?
If anyone can help I would be most grateful! Thanks.
In MySQL, you can use a join in an update:
update t join
t t2
on t2.userid = t.userid and t2.value = 'London'
set value = 'on'
where t.id = 1

MySQL - Recursive Reorder Algorithm / UPDATE with Variable Incrementation

Sorry for the kind of meaningless title, but I couldn't come up with a more fitting one.
I have a MySQL table, which looks like this:
SELECT * FROM `table`
+----+-----------+----------+-------+
| id | dimension | order_by | value |
+----+-----------+----------+-------+
| 1 | 1 | 1 | 1st |
| 2 | 1 | 100 | 3rd |
| 3 | 2 | 300 | 5th |
| 4 | 3 | 999 | 6th |
| 5 | 1 | 2 | 2nd |
| 6 | 2 | 1 | 4th |
+----+-----------+----------+-------+
I am listing all entries ordered by dimension (first) and order_by (second), which looks like this:
SELECT * FROM `table` ORDER BY `dimension`, `order_by`
+----+-----------+----------+-------+
| id | dimension | order_by | value |
+----+-----------+----------+-------+
| 1 | 1 | 1 | 1st |
| 5 | 1 | 2 | 2nd |
| 2 | 1 | 100 | 3rd |
| 6 | 2 | 1 | 4th |
| 3 | 2 | 300 | 5th |
| 4 | 3 | 999 | 6th |
+----+-----------+----------+-------+
Now I'd like to write a function, that rearranges the order_by, if possible with just one update query, to make it look that way:
SELECT * FROM `table` ORDER BY `dimension`, `order_by`
+----+-----------+----------+-------+
| id | dimension | order_by | value |
+----+-----------+----------+-------+
| 1 | 1 | 1 | 1st |
| 5 | 1 | 2 | 2nd |
| 2 | 1 | 3 | 3rd |
| 6 | 2 | 1 | 4th |
| 3 | 2 | 2 | 5th |
| 4 | 3 | 1 | 6th |
+----+-----------+----------+-------+
What I got so far (which, unfortunately, doesn't start recounting for each dimension):
UPDATE `table` AS `l`
JOIN (SELECT #i=1 FROM `table`) AS `i`
SET `order_by` = #i:=i
Now, my question would be: Is it possible to do it with just one UPDATE query?
You have to introduce another variable holding the value of the previous row.
UPDATE Table1 t
INNER JOIN (
SELECT
id, /*your primary key I assume*/
#new_ob:=if(#prev != dimension, 1, #new_ob + 1) as new_ob,
#prev := dimension /*In this line, the value of the current row is assigned. In the previous line, the variable still holds the value of the previous row*/
FROM
Table1
, (SELECT #prev := null, #new_ob := 0) var_init_subquery
ORDER BY dimension, order_by
) st ON t.id = st.id
SET t.order_by = st.new_ob;
see it working live in an sqlfiddle

How to create a simple crosstab query in MySQL

I have two tables containing fields as below.
Table 1
| SetID | InQty | Day |
| 1 | 10 | 1 |
| 2 | 10 | 2 |
| 3 | 10 | 3 |
Table 2
| SetID | OtQty | Day |
| 1 | 1 | 5 |
| 1 | 2 | 6 |
| 1 | 3 | 7 |
SetID in table 2 is linked with SetId in table 1. Day is placed in place of date, just for convenience only. Expected Output,
| Day | InQty | OtQty |
| 1 | 10 | |
| 5 | | 1 |
| 6 | | 2 |
| 7 | | 3 |
Blank Space can be filled with NULL or Zero.
It appears you are querying ONLY for set ID = 1 otherwise, I would expect to see in/out values for Set 2 and 3. You should be able to get with a simple UNION
select t1.Day, t1.InQty, 0 OutQty
from Table1 t1
where SetID = 1
order by t1.Day
union select t2.Day, 0, t2.OtQty
from Table2 t2
where SetID = 1
Now, if you want totals spanning different "setID"s and keeping them differentiated from each other, just add the setID as a column and also add to the group by clause as well.

Show the column not null of two tables in SQL

I would like to join two tables and select from two columns the first one if it is not null, of the other if the first is null. As an example imagine that we have the following tables:
names companies_to_names
-------------------------------- -----------------------------
|id_name | name | nickname | | id | id_name | id_company |
-------------------------------- -----------------------------
| 1 | NULL | manu | | 1 | 1 | 1 |
| 2 | Joe A. | NULL | | 2 | 2 | 1 |
| 3 | Bob B. | NULL | | 3 | 3 | 1 |
| 4 | NULL | alice | | 4 | 4 | 1 |
| 5 | NULL | other | | 5 | 5 | 2 |
-------------------------------- -----------------------------
And we want to show either the name, or the nickname of the guys who work for the company with id=1. Then, I want the following result:
--------------------
|id_name | username|
--------------------
| 1 | manu |
| 2 | Joe A. |
| 3 | Bob B. |
| 4 | alice |
--------------------
I was thinking in SELECT CASE WHEN, but I don't know how to do it. Something like:
SELECT NAMES.id_name CASE username
WHEN NAMES.name IS NULL THEN NAMES.nickname
WHEN NAMES.name IS NOT NULL THEN NAMES.name
END
FROM NAMES INNER JOIN COMPANIES_TO_NAMES ON NAMES.id_name = COMPANIES_TO_NAMES.id_name;
Am I right?
Here is a query that shows you how to solve your problem:
SELECT N.id_name
,IFNULL(N.name, N.nickname) AS [username]
,CASE
WHEN N.name IS NOT NULL THEN 'name'
ELSE 'nickname'
END AS [username_source]
FROM NAMES N
INNER JOIN companies_to_names C ON C.id_name = N.id_name
AND C.id = 1
Hope this will help you.

Create a column that counts the number of times a value shows up on another column, from the same table - MySQL

In MySQL:
Lets say I've this table:
id | name | count |
1 | John | |
2 | John | |
3 | John | |
4 | Mary | |
5 | Lewis| |
6 | Lewis| |
7 | Max | |
8 | Max | |
The names are already grouped, so the same name comes up together.
Now I want the table to be like this:
id | name | count |
1 | John | 1 |
2 | John | 2 |
3 | John | 3 |
4 | Mary | 1 |
5 | Lewis| 1 |
6 | Lewis| 2 |
7 | Max | 1 |
8 | Max | 2 |
Notice it auto increments the value of count everytime there is a repetition of the same name.
Thanks!
You can use a user variable.
Something like this:-
UPDATE somepeople a
INNER JOIN (
SELECT id, name, IF(#PrevName=name, #aCnt := #aCnt + 1, #aCnt := 1) AS sequence, #PrevName:=name
FROM somepeople,
(SELECT #aCnt:=1, #PrevName:='') Sub1
ORDER BY name, id) b
ON a.id = b.id
SET a.count = b.sequence