I want to switch the values if a condition is added to the sql query but i don't know exactly how work the if else statement in sql.
This is my query:
DATABASE:
attr_id
st_id
prod_id
value
Data:
$attr_id1 = "75";
$attr_id2 = "76";
$st_id = array('2','2','2','2');
$prod_id = array('2','3','4');
$value = array('150','200','300');
SQL:
"INSERT INTO table
(attr_id, st_id, prod_id, value)
VALUES (IF(value from $attr_id2 is < less that $value switch to $attr_id2 else to $attr_id1), ".$st_id.", ".$prod_id.", ".$value.")
ON DUPLICATE KEY UPDATE
value = (".$value.")";
"WHERE attr_id = ".$attr_id1." //OR ATTR_ID2
AND st_id = ".$st_id."
AND prod_id = ".$prod_id."
"
DATATABLE:
attr_id st_id prod_id value
75 2 2 150
76 2 2 200
75 2 3 300
76 2 3 290
76 2 4 200
Any help is appreciated.
You can use CASE
INSERT INTO TABLE (attr_id, st_id, prod_id, VALUE)
VALUES
(
CASE
WHEN ".$attr_id2." < ".$attr_id1."
THEN ".$attr_id2."
ELSE ".$attr_id1."
END,
".$st_id.",
".$prod_id.",
".$value."
) .....
Related
I am trying for a MySQL query to check multiple values between two columns values.
For example, for one value here is my query which works
SELECT column3
FROM table
WHERE (12 between minvaluecol AND maxvaluecol) AND
id = 123;
I would like to check multiple values like (12,13,14,67,68) and should return the values that are in between minvaluecol and maxvaluecol columns. In this case, only 12,13,14 are in between minvaluecol and maxvaluecol columns whereas 67,68 are not.
my table looks like this,
id | minvaluecol | maxvaluecol
---- | ----------- | ------------
121 | 23 | 35
123 | 10 | 20
125 | 40 | 50
output for id 123 should look like,
12 | true
13 | true
14 | true
67 | false
68 | false
Please help me with this query in MySQL. Thank you.
Update
Completely revamped the answer based on updated question.
As you need all the values as different rows, you need to SELECT all of them with UNION and LEFT JOIN it with the original table, e.g.:
SELECT a.val, IF(a.val BETWEEN tv.minvaluecol AND maxvaluecol, 'true', 'false') AS result
FROM (
SELECT 12 AS val
UNION
SELECT 13 AS val
UNION
SELECT 14 AS val
UNION
SELECT 67 AS val
UNION
SELECT 68 AS val) a
JOIN test_values tv
WHERE tv.id = 123;
Here's the SQL Fiddle.
The easiest way to get your result is to Insert those values into a table and then join like this:
SELECT value,
CASE WHEN value between minvaluecol AND maxvaluecol THEN 'true ELSE 'false' END
FROM table
CROSS JOIN table_with_values
WHERE id = 123
ORDER BY value
i have a table called ptb_profile_views that looks like this:
id | profile_id | viewed_profile_id
1 2 6
2 2 6
3 3 6
4 -1 6
5 -1 6
i have been trying to count the positive values in 'profile_id' only once as distinct values and count -1 values as many times as they appear with the following query:
function check_profile_views3() {
global $connection;
global $_SESSION;
$query = "
SELECT id,profile_id,viewed_profile_id COUNT
FROM ptb_profile_views
WHERE profile_id > 0
GROUP BY profile_id
UNION
/*shows all -1 profile id's*/
SELECT id,profile_id,viewed_profile_id
FROM ptb_profile_views
WHERE profile_id <= 0";
$check_profile_views_set3 = mysql_query($query, $connection);
confirm_query($check_profile_views_set3);
return $check_profile_views_set3;
}
so the end result is
2, 3, -1, -1
but instead of echoing out the actual values them selves i want the query to do a count of the values.
so...
2, 3, -1, -1 = a total of 4
i am also trying to call the query like so which i don't know if will work:
$check_profile_views_set3 = check_profile_views3();
while ($views3 = mysql_fetch_array($check_profile_views_set3)) {
echo "".$views3['profile_id'].""; ?>
can someone please show me how i can do this? thanks
SELECT a + b AS TotalCount
FROM
(
SELECT COUNT(DISTINCT profile_ID) a
FROM ptb_profile_views
WHERE profile_ID > 0
) x,
(
SELECT COUNT(profile_ID) b
FROM ptb_profile_views
WHERE profile_ID < 0
) y
SQLFiddle Demo
You're help would be much appreciated...
If I have the following table and sample data... myGroupTable
group_Id : user_Id
1 : 3
1 : 7
1 : 100
2 : 3
2 : 7
2 : 100
2 : 104
4 : 42
4 : 98
4 : 13
I would like a sql statement that would...
Return a group_Id that has exactly the specified user_Id's in them.
eg... is there a group_Id that has User_Id's 3, 7 and 100
answer: group_id 1.
Please note that I dont want it to return a group_Id 2, as that also has a user_Id of 104 in it...
Kind regards J
SELECT
group_Id,
SUM(
IF user_Id = 3 THEN 1
ELSEIF user_Id = 7 THEN 2
ELSEIF user_Id = 100 THEN 4
ELSE 8
) AS bits
FROM myGroupTable
GROUP BY group_Id
HAVING bits=7
This assumes that you cannot have duplicate user_Ids for the same group_Id, eg this could never happens:
group user
1 3
1 3
Edit: You can build your query in the following way:
<?php
$ids = array(3, 7, 100);
$power = 2;
$query = "
SELECT
group_Id,
SUM(
IF user_Id = " .$ids[0]. " THEN 1 ";
foreach ($id in $ids) {
$query .= " ELSEIF user_Id = $id THEN " . $power;
$power = $power * 2;
}
$query .= " ELSE $power
) AS bits
FROM myGroupTable
GROUP BY group_Id
HAVING bits = " . ($power - 1);
Here's another alternative:
SELECT group_id, GROUP_CONCAT(user_id ORDER BY user_id) AS user_id_list
FROM group_user
GROUP BY group_id
HAVING user_id_list = '3,7,100'
another solution:
SELECT group FROM tbl WHERE group_id NOT IN (SELECT DISTINCT group_id FROM tbl WHERE user_id NOT IN(3,7,100)) AND user_id IN (3,7,100);
select group_id,
sum(
case user_id in(3,7,100)
when 1 then 1
else -99
end
) as must_be_3
from group_user
group by group_id
having must_be_3=3;
Database table
id serial account speeddialsort dest
107 155 501 1 020341542
115 155 501 2 004407152222
116 155 501 3 00951242454
117 155 501 4 0794245544
118 266 700 1 004465652212
119 266 700 2 0044845482
Data presented to user
This a list of account's 501 speed dial slots.
I can send the speeddialsort and dest if required from a form, what sql method can I then use to manage user editing of the speed dial order.
The order is to be moved up or down
speeddialsort dest
#1 020341542
#2 004407152222
#3 00951242454
#4 0794245544
For example user selects speed dial #3 be moved up. The speeddialsort of #2 and #3 will need to be swapped
I asume speeddialsort is UNIQUE and dest isn't?
Asume $int_short to be supplied sort_id and $int_previous_sort to be the value is was before:
INSERT INTO table (speeddialsort, dest)
SELECT speeddialsort, dest
FROM (SELECT {$int_sort} AS speeddialsort, dest
FROM table
WHERE speeddialsort = {$int_previous_sort}
UNION ALL
SELECT {$int_previous_sort}, dest
FROM table
WHERE speeddialsort = {$int_sort})
ON DUPLICATE KEY UPDATE dest = VALUES(dest)
In case both are UNIQUE, it'd be easier to simply remove and readd them. That, or:
INSERT INTO table (speeddialsort, dest)
SELECT speeddialsort, dest
FROM (SELECT {$int_sort} AS speeddialsort, NULL AS dest
UNION ALL
SELECT {$int_previous_sort}, NULL
UNION ALL
SELECT {$int_sort}, dest
FROM table
WHERE speeddialsort = {$int_previous_sort}
UNION ALL
SELECT {$int_previous_sort}, dest
FROM table
WHERE speeddialsort = {$int_sort})
ON DUPLICATE KEY UPDATE dest = VALUES(dest)
Should work aswell.
Move Up:
UPDATE my_table AS t1 SET t1.dest =
IFNULL( ( SELECT t2.dest FROM my_table AS t2
WHERE t2.speeddialsort IN( {$i}, {$i-1} ) AND
t2.account = $account AND t2.dest <> t1.dest ), t1.dest )
WHERE t1.speeddialsort IN( {$i}, {$i-1} ) AND t1.account = {$account}
to Move Down just replace $i-1s with $i+1
($i is the speeddialsort you want to move, $account is the account id)
I create a table and the row serial is made in a continuous sequence by using
mysql user defined variable.
ID serial
101 1
103 2
104 3
110 4
In this to move the item with serial 4 to 2
SET #a = 2;
UPDATE tableName SET serial = #a:=#a + 1 WHERE serial >= 2 AND serial < 4
ORDER BY serial DESC;
UPDATE tableName SET serial = 2 WHERE ID = 1;
This query will add 1 to all the serial values less than 4 and greater than 2 and then update the row with serial 4 with value 2.
And to move item 2 to 4
SET #b = 4;
UPDATE tableName SET ord = #b:=#b - 1 WHERE serial > 2 AND serial < (4 + 1)
ORDER BY serial DESC;
UPDATE tableName SET serial = 4 WHERE ID = 1 ;
I am not talking about Auto Increment.In my case I need to order the values as user required.So i cannot use Auto increment.
I'm working with ACL in CakePHP, and would like to fetch all entries that are allowed for the current user.
Simplified, I have two tables:
Interval:
**lft**| **rght**
10 | 20
40 | 60
90 | 92
Acos:
**foreign_key** | **lft** | **rght**
3 | 15 | 17
4 | 25 | 27
5 | 45 | 47
6 | 49 | 51
7 | 81 | 83
Now I would like to fetch the foreign_keys FROM Acos which have lft and rght values between the lft and rght from Interval
In the above example we get foreign_key 3, 5, 6.
On a side note. The "Interval" table does not actually exist. The values came from this query (also the acos table):
SELECT lft, rght FROM acos WHERE id IN (
SELECT aco_id FROM aros_acos WHERE
aro_id = (SELECT parent_id FROM aros WHERE foreign_key = 48 && model = 'User' )
OR
aro_id = (SELECT id FROM aros WHERE foreign_key = 48 && model = 'User' )
)
I don't hope the example above is too messy. Please comment if there are any uncertainties.
Thank you in advance!
select distinct foreign_key
from Acos
join
(
SELECT lft, rght
FROM acos
WHERE
id IN (
SELECT aco_id
FROM
aros_acos a,
(
select parent_id, id
from aros
where foreign_key = 48 && model = 'User'
) x
WHERE
a.aro_id = x.id
OR a.aro_id = x.parent_id
)
) Interval
on
Acos.lft>=Interval.lft
and acos.rght<=Interval.rght
You can join the tables like this:
SELECT foreign_key from Acos a INNER JOIN Interval i ON
(i.lft <= a.lft AND i.rght>=a.rght)
The join condition (i.lft <= a.lft AND i.rght>=a.rght)ensures that range in Acos is within or equal to the range of Interval, without going over.
If there are multiple matching intervals, you'll get multiple rows in the result. Use a GROUP BY or DISTINCT to get just the foreign key.