SQL Query result with contains values from an array - php

I search a MySQL solution to collect queries, which contains some ints (ids in an array).
Example-Table:
id1 id2 id3
1 2 2
2 3 2
3 3 5
4 4 2
5 4 5
6 4 7
I have an array like
$id3array = (2,5);
I need id2 = 3 (not 4, because id2 "4" has one more id3 argument (7)
If I have an array like
$id3array = (2,5,6); // array can contains 20 and more arguments
In this example Table I need id2 = 0 (because no match)
My Tests with IN(2,5) or Group by was not successful - Is this possible to solve with MySQL?
http://www.sqlfiddle.com/#!9/b71306/2

Try following query. Put inner query which will match records which is not in desired array. Then group and count exact element
SELECT `id2` FROM `exampletable` WHERE `id3` IN (2,5) AND `id2` NOT IN (
SELECT e.id2 from exampletable e WHERE e.id3 not in (2,5)) GROUP BY `id2`
HAVING count(`id2`) = 2;
Here I have added count(id2) = 2 because you have 2 elements in array
DEMO

Related

How to get value from table1, search in table2, and after found - get a row value of the first value?

I have table1, here I have a data of ids from table2 - that look like that: (I dont know how to create here a table)
id | word1 | word2
1 | 5 | 7
So I want to get the word1 and word2 values from table1, search them in table2, and after that get them word_name value in table2. here`s what I do:
SELECT a.word1, a.word2, b.word_name FROM table1 a, table2 b WHERE b.id = a.word1 OR b.id = a.word2
and nothing happend.
If I understood your question correctly, here is the sample data:
id, word1_id, word2_id
CREATE TABLE IF NOT EXISTS id (`id` INT,`w1` INT,`w2` INT
);
INSERT INTO id VALUES
(1,1,5),
(2,2,4),
(3,8,3),
(4,6,2),
(5,7,1),
(6,4,9),
(7,5,7),
(8,2,6),
(9,3,8);`
Word table
CREATE TABLE IF NOT EXISTS word (
`w_id` INT,
`word` VARCHAR(5) CHARACTER SET utf8
);
INSERT INTO word VALUES
(1,'one'),
(2,'two'),
(3,'three'),
(4,'four'),
(5,'five'),
(6,'six '),
(7,'seven'),
(8,'eight'),
(9,'nine');`
And here is the answer:
select id.w1,id.w2,w1.word,w2.word from id
join word w1 on w1.w_id = id.w1
join word w2 on w2.w_id = id.w2;
7 1 seven one
6 2 six two
8 3 eight three
2 4 two four
1 5 one five
2 6 two six
5 7 five seven
3 8 three eight
4 9 four nine
and let me know if that worked.!

SQL Get max ID grouped by a second ID

I am working on a php/mysql best before date checking system and upon creating a new check I need the system to find a best before date for a certain product by looking for it most recent closed check
I am working with a few tables to get this done:
bbcheckProducts
ID checkID productID checked bestBefore
1 1 1 1 2015-05-06
2 2 1 1 2016-07-22
3 3 1 1 2016-09-16
bbChecks
checkID userID closed
1 1 1
2 2 1
3 1 1
So when I run this query on the tables in the image above:
SELECT ID,
MAX(checkID) AS maxCheck,
bestBefore
FROM bbcheckProducts
WHERE checkID IN
(
SELECT checkID
FROM bbChecks
WHERE userID = 1
AND closed = 1
)
AND checked = 1
GROUP BY productID
ORDER BY bestbefore ASC
it returns something like this:
ID = 1
maxCheck = 3
bestBefore = 2015-05-06
so it does take the max checkID but the other values remain equal to the first occurence of productID. I want it to take the values that go together with that max ID so the result would look like this:
ID=3
maxCheck = 3
bestBefore = 2016-09-16
so how do I get my query to work like that?
NOTE: there are multiple products so product one may be in check 1 and 3 while product 2 is only in 1 so it has to take the data of product 2 from check 1 and the data of product 1 from check 3
You need to use max function on second table like this query
select * from table_name where some_colomn = 'some_value' and some_colomn
in (select max(some_colomn) from table_name2 where some_col = 'some_value' group by some_colomn)
You could join your tables to get a reduced set of all record with an check_ID existing in your bbChecks-table.
Then you can run your max(CheckID)-selection on the reduced set.
In your case this would like like that:
SELECT ID, max(checkID), bestBefore
FROM bbcheckProducts p
INNER JOIN bbChecks c ON (p.checkID = c.checkID)
WHERE UserID = 1
AND closed = 1
AND checked = 1
This returns you first of alle the records with the checkIDs 1 and 3. And then you select the max(checkID), so it returns you the checkID 3.

Merge results from two different tables with different column number, ORDER them by same key

I have two tables:
Table A: ID Cars Planes Num
1 3 5 2
2 8 44 1
3 7 23 6
4 6 2 7
Table B: ID Horses Dogs Cats Elefants Num
1 3 5 2 3 3
2 8 44 1 22 4
3 7 23 4 14 8
4 6 2 3 15 5
What I need to do: I need to get all results from both tables and sort them by the "Num" Column, where the "number" actually is unique for each result from both rows.
Is it even possible to "merge" those two tables and order them by "num" or should I just get each table separately ordered and do two loops checking always for the next num jumping between tables?
Thanks
you can merge them like that with UNION .
try this:
select num from(
select num from table1
union all
select num from table2
)t
order by num asc
DEMO HERE
EDIT:
select id ,Cars,Planes, Horses,Dogs,Cats,Elefants,num from(
select id ,Cars,Planes,'No horses' Horses,'No dogs' Dogs,'No cats' Cats,'No elefants' Elefants,num from table1
union all
select id,'No cars' Cars,'No planes' Planes,Horses,dogs,Cats,Elefants, num from table2
)t
order by num asc;
DEmo with other columns
SELECT NUM FROM TABLEA
UNION ALL
SELECT NUM FROM TABLEB
ORDER BY 1

Inserting new entry and updating a whole column at the same time

I have a somewhat complex problem that needs fixing, for now I have the following table structure (task_schedule):
id taskid productid product_position
1 1 1 1
2 2 1 2
3 3 2 1
4 4 1 3
5 5 2 2
6 6 3 1
product_position works the following way: it should look at the productid and increment from the previous max value entry.
I accomplish this with the following query (probably easier to understand too):
INSERT into task_schedule (taskid, productid, product_position)
SELECT 1,1, max(product_position) + 1
FROM task_schedule
WHERE productid=1
(the values are of course attributed in the php backend)
I need a new column now though. Lets call it user_position, I'm going to recreate my table with an example:
id taskid productid product_position user_position
1 1 1 1 1
2 2 1 2 4
3 3 2 1 2
4 4 1 3 6
5 5 2 2 5
6 6 3 1 3
OK, so how this should work is: user_position should individually run through each entry and look at the productid, it should build a position list based on an even order of priority.
So if I ordered this by user_position I would get the following entry id list: 1 3 6 2 5 4
An example of what I need done in php:
Imagine the following list: red red red green green green green blue blue yellow
$array1 = array(array("red"), array("red"), array("red"));
$array2 = array(array("green"), array("green"), array("green"), array("green"));
$array3 = array(array("blue"), array("blue"));
$array4 = array(array("yellow"));
$Arrays= array ($array1, $array2, $array3, $array4);
foreach ($Arrays as $type => $list) {
$ArrayLength[]=count($list);
}
$MergeArray=array();
$flag=true;
for($i=0;$flag==true;$i++)
{
$flag=false;
for($j=0;$j < count($ArrayLength);$j++)
{
if( $i < $ArrayLength[$j] )
{
array_push( $MergeArray , $Arrays[$j][$i] );
$flag=true;
}
}
}
echo "<pre>".Print_r(json_encode($MergeArray), true)."</pre>";
This returns me a consistent list with the pattern I desire:
[["red"],["green"],["blue"],["yellow"],["red"],["green"],["blue"],["red"],["green"],["green"]]
All of the above is just an example of what I need, but implemented via MySQL.
I don't even know how to approach this issue now though, I need a way to insert new entries AND update the user_position column accordingly.
If I was to add a new entry into my table, with a new peoduct_id, this should be the end result:
id taskid productid product_position user_position
1 1 1 1 1
2 2 1 2 5
3 3 2 1 2
4 4 1 3 7
5 5 2 2 6
6 6 3 1 3
7 7 4 1 4
Notice how the user_position shifted to accommodate the new row.
I think this is a fairly complex problem to solve (or maybe my mysql is just THAT weak), I don't think there is a easy solution for this one, so any input you might have on how to approach this via mysql (mysql doing the heavy lifting would be fantastic), but I welcome a PHP solution as well with multiple queries and whatnot. Unfortunately I can't drop this column, it's easy to grab entries and let PHP sort my information, but I really need this implemented in the database.
Any input from the community would be great really.
Insert using the normal insert query which you are using
INSERT into task_schedule (taskid, productid, product_position, user_position)
SELECT 1,1, max(product_position) + 1, 0 FROM task_schedule WHERE productid=1;
And then update all the entries based on product_position using the below
SET #counter = 0;
UPDATE task_schedule SET user_position = #counter := #counter + 1 ORDER BY product_position asc, productid asc;
Here is the SQL fiddle link

get SUM of another row of GROUP BY'd rows

I have this table:
This selection is is duplicated many times for different var_lines (which pretty much work as one row of data, or respondent for a survey) and set_codes (different survey codes).
With this query:
SELECT
*, COUNT(*) AS total
FROM
`data`
WHERE
`var_name` = 'GND.NEWS.INT'
AND(
`set_code` = 'BAN11A-GND'
OR `set_code` = 'BAN09A-GND'
OR `set_code` = 'ALG11A-GND'
)
AND `country_id` = '5'
GROUP BY
`data_content`,
`set_code`
ORDER BY
`set_code`,
`data_content`
The query basically counts the number of answers for a specific question. Then groups them survey (set_code).
What I need is for each of the grouped data_content answers for GND.NEWS.INT to also show the SUM of all the corresponding GND_WT with the same var_line.
For example if I had this:
data_id data_content var_name var_line
1 2 GND.NEW.INT 1
2 1.4 GND_WT 1
3 2 GND.NEW.INT 2
4 1.6 GND_WT 2
5 3 GND.NEW.INT 3
6 0.6 GND_WT 3
I would get something like this:
data_id data_content var_name var_line total weight
1 2 GND.NEW.INT 1 2 3
5 3 GND.NEW.INT 3 1 0.6
Thanks for any help.
Your requirements are not exactly clear, but I think the following gives you what you want:
select d1.data_id,
d1.data_content,
d1.var_name,
d1.var_line,
t.total,
w.weight
from data d1
inner join
(
select data_content,
count(data_content) Total
from data
group by data_content
) t
on d1.data_content = t.data_content
inner join
(
select var_line,
sum(case when var_name = 'GND_WT' then data_content end) weight
from data
group by var_line
) w
on d1.var_line = w.var_line
where d1.var_name = 'GND.NEW.INT'
See SQL Fiddle with Demo
This Query can be suitable for your specific example:
select st.data_id,
st.data_content,
st.var_name,
st.var_line,
count(st.data_id) as total,
sum(st1.data_content) as weight
from data st
left join data st1 on st1.var_name = 'GND_WT' AND st1.var_line=st.var_line
where st.var_name='GND.NEW.INT'
group by st.data_content
Regards,
Luis.

Categories