IF EXISTS do this.. stumped =x - php

So I want to insert into a table if there isn't an existing row matching conditions such as only allowing one "like" per 24-hours for the same product.
I have it nailed down to this so far, but now I need to take the hash and join in the id when making the insert. I've read that using DUAL doesn't allow joining in from other tables so I'm stumped here.
Any tips will be greatly appreciated :)
Thanks!
INSERT INTO platform.contentLikes
SELECT contents.contentId, 500000, NOW()
FROM DUAL
WHERE NOT EXISTS ( SELECT contentId, contents.contentId FROM platform.contentLikes
INNER JOIN platform.contents ON contents.hash = 'de9f21c14c1ab0bcca014825f8b09e76'
WHERE contentId = contents.contentId AND userId = 50000 )

INSERT INTO platform.contentLikes
SELECT rs.contentId, 500000, NOW()
FROM ( SELECT contents.contentId
FROM platform.contents LEFT JOIN platform.contentLikes ON contentLikes.contentId = contents.contentId AND contents.hash = 'de9f21c14c1ab0bcca014825f8b09e76' AND userId = 50000
WHERE contentLikes.contentId IS NULL)
rs
another option would be to get the contentID in your php code, and create your insert query with the contentID coded in:
$sql = 'INSERT INTO platform.contentLikes
SELECT ' . $contentId . ', 500000, NOW()

Related

Which Clause to use instead of IN Clause in MYSQL

My Question is
Which Clause use instead of IN Clause in MYSQL with PHP
Because IN Clause Limit 1024 character.
My Character limit exceed to 1024 character.
SELECT * FROM TblUser
WHERE Status != 'Deleted' AND UserId IN (0,10,11,12,13,14,15,22,45,114,144,155,156,167,211,439,440,441,443,445,450,455,456,457,458,459,1111,1154,1156,1165,1451,1541,11111,11112,11113,11114,11115,11116,11117,11118,11119,11656,15451,16561,17671,18781,33131,33311,33411,54511,111110,111111,111112,111113,111114,111115,111116,111117,111118,111119,111120,111121,111122,111123,111124,111125,111126,111127,111128,111129,111130,111131,111132,111133,111134,111135,111136,111137,111138,111139,111140,111141,111142,111143,111144,111145,111146,111147,111148,111149,111150,111151,111152,111153,111154,111155,111156,111157,111158,111159,111160,111161,111162,111163,111164,111165,111166,111167,111168,111169,111170,111171,111172,111173,111174,111175,111176,111177,111178,111179,111180,111181,111182,111183,111184,111185,111186,111187,111188,111189,111190,111191,111192,111193,111194,111195,111196,111197,111198,111199,1111100,11112101,11112102,11112103,11112104,11112105,11112106,11112107,11112108,11112109,11112110,11112111,11112112,11112113,11112114,11112115,11112116,11112117,11112118,11112119,11112120,11112121,11112122,11112123,11112124,11112125,11112126,11112127,11112128,11112129,11112130,11112131,11112132,11112133,11112134,11112135,11112136,11112137,11112138,11112139,11112140,11112141,11112142,11112143,11112144,11112145,11112146,11112147,11112148,11112149,11112150,11112151,11112152,11112153,11112154,11112155,11112156,11112157,11112158,11112159,11112160,11112161,11112162,11112163,11112164,11112165,11112166,11112167,11112168,11112169,11112170,11112171,11112172,11112173,11112174,11112175,11112176,11112177,11112178,11112179,11112180,11112181,11112182,11112183,11112184,11112185,11112186,11112187,11112188,11112189,11112190,11112191,11112192,11112193,11112194,11112195,11112196,11112197,11112198,11112199,11112200);
Please help Which Clause use instead of IN Clause in MYSQL with PHP?
Is the list of values that are used in the IN statement always the same, or is that list the result of some other query? If the latter is the case, you could use that query as a subquery:
SELECT * FROM tbluser
WHERE status != 'Deleted'
AND userid IN
( SELECT userid FROM sometable WHERE ... )
Yes you are limited within an IN statement, one thing you could do is create a temporary table which stores the values.
CREATE TEMPORARY TABLE IF NOT EXISTS temp AS (SELECT userid FROM tbluser);
In PHP create your INSERT INTO script:
$str = '0,10,11,12,13,14,15,22,45,114,144,155,156,167,211,439,440,441,443,445,450,455,456,457,458,459,1111,1154,1156,1165,1451,1541,11111,11112,11113,11114,11115,11116,11117,11118,11119,11656,15451,16561,17671,18781,33131,33311,33411,54511,111110,111111,111112,111113,111114,111115,111116,111117,111118,111119,111120,111121,111122,111123,111124,111125,111126,111127,111128,111129,111130,111131,111132,111133,111134,111135,111136,111137,111138,111139,111140,111141,111142,111143,111144,111145,111146,111147,111148,111149,111150,111151,111152,111153,111154,111155,111156,111157,111158,111159,111160,111161,111162,111163,111164,111165,111166,111167,111168,111169,111170,111171,111172,111173,111174,111175,111176,111177,111178,111179,111180,111181,111182,111183,111184,111185,111186,111187,111188,111189,111190,111191,111192,111193,111194,111195,111196,111197,111198,111199,1111100,11112101,11112102,11112103,11112104,11112105,11112106,11112107,11112108,11112109,11112110,11112111,11112112,11112113,11112114,11112115,11112116,11112117,11112118,11112119,11112120,11112121,11112122,11112123,11112124,11112125,11112126,11112127,11112128,11112129,11112130,11112131,11112132,11112133,11112134,11112135,11112136,11112137,11112138,11112139,11112140,11112141,11112142,11112143,11112144,11112145,11112146,11112147,11112148,11112149,11112150,11112151,11112152,11112153,11112154,11112155,11112156,11112157,11112158,11112159,11112160,11112161,11112162,11112163,11112164,11112165,11112166,11112167,11112168,11112169,11112170,11112171,11112172,11112173,11112174,11112175,11112176,11112177,11112178,11112179,11112180,11112181,11112182,11112183,11112184,11112185,11112186,11112187,11112188,11112189,11112190,11112191,11112192,11112193,11112194,11112195,11112196,11112197,11112198,11112199,11112200';
$ids = explode(',', $str);
foreach ($ids as $value){
echo 'INSERT INTO temp VALUES(' . $value . '); </br>';
}
But change the echo for the mysqli query.
Then:
SELECT * FROM tbluser u
where status !='Deleted'
And exists(select * from temp u1 where u1.userid = u.userid)
Or you can do an inner join temp u1 on u1.userid = u.userid
#Abid as you mentioned your question in this case #Guss is right.
What i am thinking if values mentioned IN clause comes from GROUP_CONCAT then might be possible duplicate values exist with comma seperated. So to remove duplicacy we can use DISTINCT.
For example :
SELECT GROUP_CONCAT(UserId) FROM sometable
Above query can give duplicate values.
SELECT GROUP_CONCAT(DISTINCT UserId) FROM sometable
SELECT t1.UserRoleId, t1.EntityId, GROUP_CONCAT( DISTINCT t1.PermissionId ) AS Permissions
FROM userpermission t1, bill_companies t2
WHERE t1.Status = 'Active'
AND t2.status = 'Active'
AND UserGroupId
IN ( 84, 85, 86 )
LIMIT 0 , 30
Above query gives you userid's without duplicacy. This can also reduce the size of comma seperated ids.
Hope this will help.
You could create groups using php if there are Ids which follow by increment e. g. 1,2,3 and replace them by a OR (id >= 1 AND id <= 3)
Alternative approach:
Search Max and Min ID in your List and query using an interval (greater than and less than) and use php to do the job.
If you really want to avoid using IN then you could use FIND_IN_SET():-
SELECT * FROM TblUser
WHERE Status != 'Deleted' AND FIND_IN_SET(UserId, '0,10,11,12,13,14,15,22,45,114,144,155,156,167,211,439,440,441,443,445,450,455,456,457,458,459,1111,1154,1156,1165,1451,1541,11111,11112,11113,11114,11115,11116,11117,11118,11119,11656,15451,16561,17671,18781,33131,33311,33411,54511,111110,111111,111112,111113,111114,111115,111116,111117,111118,111119,111120,111121,111122,111123,111124,111125,111126,111127,111128,111129,111130,111131,111132,111133,111134,111135,111136,111137,111138,111139,111140,111141,111142,111143,111144,111145,111146,111147,111148,111149,111150,111151,111152,111153,111154,111155,111156,111157,111158,111159,111160,111161,111162,111163,111164,111165,111166,111167,111168,111169,111170,111171,111172,111173,111174,111175,111176,111177,111178,111179,111180,111181,111182,111183,111184,111185,111186,111187,111188,111189,111190,111191,111192,111193,111194,111195,111196,111197,111198,111199,1111100,11112101,11112102,11112103,11112104,11112105,11112106,11112107,11112108,11112109,11112110,11112111,11112112,11112113,11112114,11112115,11112116,11112117,11112118,11112119,11112120,11112121,11112122,11112123,11112124,11112125,11112126,11112127,11112128,11112129,11112130,11112131,11112132,11112133,11112134,11112135,11112136,11112137,11112138,11112139,11112140,11112141,11112142,11112143,11112144,11112145,11112146,11112147,11112148,11112149,11112150,11112151,11112152,11112153,11112154,11112155,11112156,11112157,11112158,11112159,11112160,11112161,11112162,11112163,11112164,11112165,11112166,11112167,11112168,11112169,11112170,11112171,11112172,11112173,11112174,11112175,11112176,11112177,11112178,11112179,11112180,11112181,11112182,11112183,11112184,11112185,11112186,11112187,11112188,11112189,11112190,11112191,11112192,11112193,11112194,11112195,11112196,11112197,11112198,11112199,11112200')
However the only limit for the number of entries in an IN clause is set by max_allowed_packet (as others have stated) and the same restriction would apply to this.
max_allowed_packet

PHP/MySQL Using multiple WHEREs in one SELECT query

I have 2 tables.
Table A: trades: which contains the columns: tradeID, tradeName, tradeShow, and tradeGuy.
Table B: offers: which contains the columns: tradeID, offerName, offerGuy.
I'm trying to select all columns from table A (trades) WHERE the value of "tradeShow" = 'Yes', And the value of "tradeGuy" != the user's Username. That much is easy, but I also don't want to select any records which have an offer created by the user. In other words, in table B (offers), offerGuy != Username WHERE trade ID from Table B = tradeID from Table A.
But, how do I merge these 2 conditions? I've tried this:
$sql = "SELECT *
FROM trades t1
JOIN offers t2
ON (t1.tradeID = t2.tradeID)
WHERE t1.tradeShow='Yes' AND t1.tradeGuy!='$username' AND t2.offeringGuy!='$username'";
But the problem with that is it only selects the records from trades which have an offer, because of the forth line: ON (t1.tradeID = t2.tradeID), as in it only selects trades which have a record in (offers) that mentions their tradeID.
I've also tried an awkward attempt to link the 2 tables with a meaningless link by adding a "linker" column to each table with the default value of "XXX", and did this:
$sql = "SELECT *
FROM trades t1
JOIN offers t2
ON (t1.linkerA = t2.linkerB)
WHERE t1.tradeShow='Yes' AND t1.tradeGuy!='$username' AND (t2.offeringGuy!='$username' WHERE t1.tradeID=t2.tradeID)";
But the problem with that is using 2 Where clauses...
So, how do I merge the 2 conditions?
What you're looking for is called an OUTER JOIN (in this case a LEFT OUTER JOIN) which will give you null results for missing matches, something like;
SELECT *
FROM trades t1
LEFT OUTER JOIN offers t2
ON t1.tradeID = t2.tradeID AND t2.offeringGuy = '$username'
WHERE t1.tradeShow='Yes' AND t1.tradeGuy!='$username' AND t2.offeringGuy IS NULL
We add a condition to the LEFT JOIN that we're only interested in matches against t2.offeringGuy = '$username', which will return NULL values in t2's fields if there is no match.
Then we just check that t2.offeringGuy IS NULL to find the non matches.
I would do this with not exists rather than an explicit join:
SELECT *
FROM trades t
WHERE t.tradeShow = 'Yes' AND t.tradeGuy <> '$username' and
not exists (select 1
from offers o
where t.tradeID = o.tradeID and o.tradeGuy = '$username'
);

MySql - if there is no record, insert multiple rows

Before asking this question, I already search a lot of entries on Google and StockOverflow. Nothing can fulfil my question.
There are two tables - group_sale_bonuses and members. I want to check is already there records with product_id "1" in the group_sale_bonuses.
If not, I want to insert all records from members table into group_sale_bonuses with product_id "1".
My overall requirement is as follow:
IF ((Select count(id) from group_sale_bonuses where product_id = 1) = 0) THEN
INSERT INTO group_sale_bonuses (member_id, product_id, quantity_counter, credit)
SELECT id, 1, 0, 0 FROM members
END IF
But this sql causes the errors.
I know there are solutions about Insert Ignore, Where Not Exists.
But these conditions checking are based on per each record. I have thousands of records in members table. I want to make condition checking just one time like in my above sql example.
By the way, I will use this Sql in Php web application.
You could just set the code in a WHERE clause instead of the IF.
INSERT INTO group_sale_bonuses(
member_id,
product_id,
quantity_counter,
credit)
SELECT
id, 1, 0, 0 FROM members
WHERE(
SELECT
count(id) FROM group_sale_bonuses
WHERE product_id = 1
) = 0;
This should do it for all product_id's
SELECT m.product_id, m.member_id FROM members AS m
LEFT JOIN group_sale_bonuses AS gsb ON gsb.product_id = m.product_id
WHERE gsb.product_id IS NULL ;
You can filter it to a specific product_id by adding to the where clause
SELECT m.product_id, m.member_id FROM members AS m
LEFT JOIN group_sale_bonuses AS gsb ON gsb.product_id = m.product_id
WHERE gsb.product_id IS NULL AND m.product_id = 1;
Take a look at this SQLfiddle: http://sqlfiddle.com/#!2/8482c/2

Php and MySql - copy data from one to another table

I just want to know how if it is possible to copy data from one table column to another in the same database? The code below is not working with my version of MySQL but it should be working.
UPDATE `table1` SET `table1.column1` =
(SELECT `table2.column2` FROM table2 WHERE `table1.city` = 'table2.city')
WHERE `listing` ='5'
Do you have some idea ?
Thanks !
Guys, As I thought solution is possible with php script and solution for this problem is to make a short script which is gonna do all this up with while loop :)
Thanks everybody on joining this discussions !
The solution was in `` marks between them should be column names,
this works nice, enjoy !
Yes you can do with INSERT ... SELECT Syntax like:
INSERT INTO database2.table1 (field1,field3,field9)
SELECT table2.field3,table2.field1,table2.field4
FROM table2;
Check Mysql
It reads like you're attempting to perform an update, not an insert.
UPDATE table1 AS t1 INNER JOIN table2 AS t2 ON t1.city=t2.city
SET t1.column1 = t2.column2
WHERE t1.listing ='5'
In the case that you do need to copy data from one table to the other then you need to follow this syntax:
INSERT INTO tablename (field1,field2,field3) (SELECT field1,field2,field3 FROM another_table);
Try this.
UPDATE table1, (
SELECT table2.city, table2.column2
FROM table2 ) table2
SET table1.column1 = table2.column2
WHERE table1.city = table2.city
AND listing ='5'
Try with
INSERT INTO table2
AS (SELECT *
FROM table1
WHERE table1.city = table2.city AND
listing = 5);
as per column try like
INSERT INTO table2 (columnname1) values (SELECT columnname1 FROM table1
WHERE table1.city = table2.city AND
listing = 5);

Select IDs not in database

I have an array of products IDs and I need to find the IDs that are not present in the database. Sure I can do it like this:
// IDs in database: 1, 2, 3, 4, 5.
$products = array(4, 5, 6, 7);
$in_db = $db->exec("SELECT `id` FROM `table` WHERE `id` IN (" . implode($products) . ");");
$in_db_ids = array();
foreach($in_db as $i){
$in_db_ids[] = $i['id'];
}
$missing = array_diff($products, $in_db_ids);
But this is long and boring. I thought also about something like this:
// this query would be generated with PHP using an implode or something
$query = "
SELECT `t`.`id` as `missing`
SELECT 4 as `id` UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
LEFT JOIN `table` USING(`id`)
WHERE `missing` is NULL;
";
$missing = $db->exec($query);
But this is so inelegant.
I think there should be a proper way to write that SELECT x UNION SELECT y UNION SELECT z, or there may be another nice way to do this check.
What do you think, guys?
To do it in the MySQL database, you will need a table or a temporary table that has a number of rows equal to the highest index in the table you are scanning for missing blanks. There is no way around this -- MySQL always "loops" through tables, it isn't a procedural language where you can set up your own loop.
That being said, if you create or have a table of sufficient size, you can create the natural number sequence using a user variable. Let's call the big table bigtable (it doesn't matter what columns are in it - we just need a name of one of the columns - I use 'acolumn').
set #row = 0;
select n from
(select #row := #row + 1 as n from bigtable) as t
left join mytable on mytable.id = t.n
where mytable.acolumn is null;
Let me know if this needs a little more explanation.

Categories