Mysql filter by multiply ids - mysql

I can't finish writing query to filter row by multiply ids. Here is query:
select distinct `storage_file`.*, `storage_tag`.`id` as `tid` from `storage_file`
inner join `storage_file_tag` on `storage_file`.`id` = `storage_file_tag`.`storage_file_id`
inner join `storage_tag` on `storage_tag`.`id` = `storage_file_tag`.`storage_tag_id`
where `storage_file`.`user_id` = 17 and `storage_file`.`deleted_at` is null and
`storage_tag`.`id` IN(13,17);
So the result is without group by statement is:
So.. I need result only with two records which contain tid 13 and 17
And when i replace "IN(13,17)" with storage_tag.id = 13 AND storage_tag.id = 17 - i get no records at all
How can i write subquery which will work like a + b but not a OR b ?

I'm not sure what you do exactly but it seams, that the distinct is not working as you expect, because you select "*" from storage_file, as there are different values in the columns of storage_file, the result is distincted but over all selected columnns and so more the two are selected.

You can replace
... AND id IN (11,22)
with
... AND ( id = 11 OR id = 12)
You need the parentheses because WHERE operator precedence rules are very simple.
Of course,
... AND id = 11 AND id = 12
never returns anything because the id cannot have two different values at the same time.

Related

MySQL empty rows show up only if table is empty

I have 2 MySQL tables, one is named _campi (Italian for fields) and one is documenti (Italian for documents).
I need to show all the rows from _campi and where there is a match in documenti this has to show in a field as result.
The weird behavior I cannot understand is that if documentitable is empty I get the expected result (10 rows with many null values, expected result), if documenti IS NOT empty I get only 2 rows as result.
This is the query:
SELECT *, campi_tipologie.valore_campo as tipo_doc FROM _campi as campi_tipologie
LEFT JOIN documenti
ON documenti.doc_type = campi_tipologie.id_campo
WHERE campi_tipologie.categoria = "documenti-immobili"
AND (campi_tipologie.codec = 2 OR campi_tipologie.codec = 0)
AND (documenti.id_immobile IS NULL OR documenti.id_immobile = 422)
ORDER BY id_campo
What am I doing wrong?
SELECT campi
, I
, actually
, want
, c.valore_campo tipo_doc
FROM _campi c
LEFT
JOIN documenti d
ON d.doc_type = c.id_campo
AND d.id_immobile = 422
WHERE c.categoria = "documenti-immobili"
AND c.codec IN(2,0)
AND d.id_immobile IS NULL -- or omit this
ORDER
BY c.id_campo

SQL unwanted results in NOT query

This looks like it should be really easy question, but I've been looking for an answer for the past two days and can't find it. Please help!
I have two tables along the lines of
texts.text_id, texts.other_stuff...
pairs.pair_id, pairs.textA, pairs.textB
The second table defines pairs of entries from the first table.
What I need is the reverse of an ordinary LEFT JOIN query like:
SELECT texts.text_id
FROM texts
LEFT JOIN text_pairs
ON texts.text_id = text_pairs.textA
WHERE text_pairs.textB = 123
ORDER BY texts.text_id
How do I get exclusively the texts that are not paired with A given textB? I've tried
WHERE text_pairs.textB != 123 OR WHERE text_pairs.textB IS NULL
However, this returns all the pairs where textB is not 123. So, in a situation like
textA TextB
1 3
1 4
2 4
if I ask for textB != 3, the query returns 1 and 2. I need something that will just give me 1.
The comparison on the second table goes in the ON clause. Then you add a condition to see if there is no match:
SELECT t.text_id
FROM texts t LEFT JOIN
text_pairs tp
ON t.text_id = tp.textA AND tp.textB = 123
WHERE tp.textB IS NULL
ORDER BY t.text_id ;
This logic is often expressed using NOT EXISTS or NOT IN:
select t.*
from texts t
where not exists (select 1
from text_pairs tp
where t.text_id = tp.textA AND tp.textB = 123
);

MySQL COUNT() GROUP BY doesn't work

I have a problem in counting by MySQL in a GROUP BY
This is the query that does not return the desired result.
SELECT COUNT(bagno)
FROM disposizione_assegnazione_pezze
JOIN pezze
ON pezza = id
WHERE id_prodotto_tessuto = 12096
AND id_collezione = 11
AND id_stagione = 22
AND id_tema = 1
GROUP BY bagno
The result of the count is 3
This is the pezza table and its primary key is id
This is the table disposizione_assegnazione_pezze that has the pezza column which refers to the previous table
Why does not return 1 as a result my query?
Question of the problem
I want to count how many different bagno are there
I dont think you need GROUP BY, instead use DISTINCT
SELECT COUNT(DISTINCT bagno)
SQL DEMO
Check your query without agregatted function COUNT/GROUP BY
As you can see bagno = 55 appear three times, that is why when you group by bagno and count get 3.

mySQL count occurances of value on multiple fields. How?

I have a table with 5 fields. Each field can store a number from 1 - 59.
Similar to countif in Excel, how do I count the number of times a number from 1 - 59 shows up in all 5 fields?
Here's an example for the count of occurances for the number 1 in all five fields:
SELECT SUM(pick_1 = 1 OR pick_2 = 1 OR pick_3 = 1 OR pick_4 = 1 OR pick_5 = 1) AS total_count_1
FROM tbldraw
Hopefully I made sense.
There was an answer here that had a solution. I think this is just a variation.
Step1: Create a numbers table (1 field, called id, 59 records (values 1 -59))
Step2:
SELECT numbers_table.number as number
, COUNT(tbldraw.pk_record)
FROM numbers_table
LEFT JOIN tbldraw
ON numbers_table.number = tbldraw.pick_1
OR numbers_table.number = tbldraw.pick_2
OR numbers_table.number = tbldraw.pick_3
OR numbers_table.number = tbldraw.pick_4
OR numbers_table.number = tbldraw.pick_5
GROUP BY number
ORDER BY number
How about a two step process? Assuming a table called summary_table ( int id, int ttl), for each number you care about...
insert into summary_table values (1,
(select count(*)
from table
where field1 = 1 or field2 = 1 or field3 = 1 or field4 = 1 or field5 = 1))
do that 59 times, once for each value. You can use a loop in most cases. Then you can select from the summary_table
select *
from summary_table
order by id
That will do it. I leave the coversion of this SQL into a stored procedure for those that know what database is in use.
The ALL() function, which returns true if the preceding operator is true for all parameters, makes the query particularly elegant and succinct.
To find the count a particular number (eg 3):
select count(*)
from tbldraw
where 3 = all (pick_1, pick_2, pick_3, pick_4, pick_5)
To find the count of all such numbers:
select pick_1, count(*)
from tbldraw
where pick_1 = all (pick_2, pick_3, pick_4, pick_5)
group by pick_1

mysql lookup match

I have a database column like this:
id
50
55
56
62
63
64
65
68
70
72
80
etc...
I want to iterate through the id column with the following formula to find if the result of the formula is an id number in the same column. I want to compute all the possible combinations of the set of basically 3 records in the id column.
First loop:
Does ((second_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
Per the formula, the first loop is
(55-50)*2.00(as an example of variable decimal) + 55 = 65. 65 is in the list => 65 is tagged with the 2 records which equal it
Second loop:
Does ((third_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
(56-50)*2.00(as an example of variable decimal) + 56 = 78. 78 is not in the list => 78 is not tagged
Third loop:
Does ((fourth_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
etc...
I want the results to show all the tagged records. A tagged record is the set of the 3 records where the third record is the result from the formula.
Anyone got any ideas? Is it possible in mysql?
Thank you
If I'm understanding your requirements properly, it sounds like you'd want to use a self-join on the table, e.g.
SELECT ...
FROM yourtable AS parent
LEFT JOIN yourtable AS child ON
FLOOR((parent.second_id_number - parent.first_id_number) * variable) + parent.second_id) = child.id
You could potentially carry something like this forward, which satisfies your first "loop"
select a.id as first_id_number
, b.id as second_id_number
, ((b.id - a.id) * 2) + b.id as third_id_number
from my_table as a
join my_table as b on a.id = (select max(id) from my_table where id < b.id)
where ((b.id - a.id) * 2) + b.id in (select id from my_table)
According to your description and test data, this would show 65 as "tagged" with first_id_number 50 and 62.
Warning: done on SQL Server using what I think is fairly standard syntax. I would understand if some would rather phrase this as a cross join with the select max... bit in the where clause rather than in the join predicate.