I have the following table for storing user data:
eg
TABLE: users
COLUMNS:
...
maritalStatus (INT) - FK
gender (CHAR)
occupation (INT) - FK
...
Now I want to compare two users in this table to see how many columns match for any two given users (say user X & user Y)
I am doing it via mySQL Stored Procedures by getting each value separately and then comparing them
eg
SELECT maritalStatus from users where userID = X INTO myVar1;
SELECT maritalStatus from users where userID = Y INTO myVar2;
IF myVar1 = myVar2 THEN
...
END IF;
Is there a shorter way using an SQL query where I can compare two rows in a table and see which columns are different? I dont need to know how much different they actually are, just need to know if they contain the same value. Also I will only be comparing selected columns, not every column in the user table.
This will select the number of columns that are not the same for user x
and user y
:
SELECT ( u1.martialStatus <> u2.martialStatus )
+ ( u1.gender <> u2.gender )
+ ( u1.occupation <> u2.occupation )
FROM
users u1,
users u2
WHERE u1.id = x
AND u2.id = y
You can also use this:
select
-- add other columns as needed
(a.lastname,a.gender)
= (b.lastname,a.gender) as similar,
a.lastname as a_lastname,
a.firstname as a_firstname,
a.age as a_age,
'x' as x,
b.lastname as b_lastname,
b.firstname as b_firstname,
b.age as b_age
from person a
cross join person b
where a.id = 1 and b.id = 2
Output:
SIMILAR A_LASTNAME A_FIRSTNAME A_AGE X B_LASTNAME B_FIRSTNAME B_AGE
1 Lennon John 40 x Lennon Julian 15
Live test: http://www.sqlfiddle.com/#!2/840a1/2
You can count the number of users with the same columns using group by
:
select u1.maritalStatus
, u1.gender
, u1.occupation
, count(*)
from users u1
group by
u1.maritalStatus
, u1.gender
, u1.occupation
Just a continued example of Peter Langs suggestion in PHP:
$arr_cols = array('martialStatus', 'gender', 'occupation');
$arr_where = array();
$arr_select = array();
foreach($arr_cols as $h) {
$arr_having[] = "compare_{$h}";
$arr_select[] = "(u1.{$h} != u2.{$h}) AS compare_{$h}";
}
$str_having = implode(' + ', $arr_where);
$str_select = implode(', ', $arr_where);
$query = mysql_query("
SELECT {$str_select}
FROM users AS u1, users AS u2
WHERE u1.userid = {$int_userid_1} AND u2.userid = {$int_userid_2}
HAVING {$str_having} > 0
");
/* Having case can be removed if you need the row regardless. */
/* Afterwards you check these values: */
$row = mysql_fetch_assoc($query);
foreach($arr_cols as $h)
if ($row["compare_{$h}"])
echo "Found difference in column {$h}!";
I think, this may help someone. Objective: To find rows with same name and update new records date with the old record. This could be a condition where you will have to duplicate news item for different countryand keep the same date as original.
CREATE TABLE `t` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `locale` varchar(10) DEFAULT 'en', `title` varchar(255) DEFAULT NULL, `slug` varchar(255) DEFAULT NULL, `body` text, `image` varchar(255) DEFAULT NULL, `thumb` varchar(255) DEFAULT NULL, `slug_title` varchar(255) DEFAULT NULL, `excerpt` text, `meta_title` varchar(200) DEFAULT NULL, `meta_description` varchar(160) DEFAULT NULL, `other_meta_tags` text, `read_count` int(10) DEFAULT '0', `status` varchar(20) DEFAULT NULL, `revised` text, `created` datetime DEFAULT NULL, `modified` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8; INSERT INTO `t` (`id`, `locale`, `title`, `slug`, `body`, `image`, `thumb`, `slug_title`, `excerpt`, `meta_title`, `meta_description`, `other_meta_tags`, `read_count`, `status`, `revised`, `created`, `modified`) VALUES (2, 'en', 'A title once again', '/news/title-one-again', 'And the article body follows.', '/uploads/2014/11/telecommunications100x100.jpg', NULL, NULL, NULL, '', '', NULL, 0, 'Draft', NULL, '2014-09-22 12:26:17', '2014-10-23 10:13:21'), (3, 'en', 'A title once again', '/news/title-strikes-back', 'This is really exciting! Not.', '/uploads/2014/11/telecommunications100x100.jpg', NULL, NULL, NULL, '', '', NULL, 0, 'Unpublished', NULL, '2014-09-23 12:26:17', '2014-10-31 11:12:55'), (4, 'en_GB', 'test', '/news/test', 'test', '/uploads/2014/11/telecommunications100x100.jpg', NULL, NULL, NULL, '', '', NULL, 0, 'Published', NULL, '2014-10-23 10:14:30', '2014-10-23 10:14:30'); update t join t t2 on t.title = t2.title set t2.created = t.created where t.title = t2.title ;
update t join t t2 on t.title = t2.title set t2.created = t.created where t.title = t2.title ;
In the event another Magento developer finds their way here, a specific use for this Q/A is to compare two address entries in a table. "Magento 1" will put the same address in twice with the only differences being the key entity_id
column and address_type
column ( billing or shipping ).
Already knowing the order's entity_id
, use this to get the billing and shipping address IDs associated with the order:
SELECT entity_id FROM sales_flat_order_address WHERE parent_id = 3137;
Then to see if they differ for that order:
SELECT a1.parent_id AS 'order_id'
, ( a1.street <> a2.street )
+ ( a1.city <> a2.city )
+ ( a1.postcode <> a2.postcode )
+ ( a1.region_id <> a2.region_id )
AS 'diffs'
FROM
sales_flat_order_address a1,
sales_flat_order_address a2
WHERE a1.entity_id = 6273
AND a2.entity_id = 6274
;
Gives the output:
+----------+-------+
| order_id | diffs |
+----------+-------+
| 3137 | 0 |
+----------+-------+
It would be fantastic if there was a way to do this en masse.
If you want to find out which columns have different values in two rows of a table, you can use the following query:
SET @table_name = 'YOUR_TABLE_NAME';
SET @primary_column_name = 'PRIMARY_COLUMN_NAME';
SET @row1_id = '1234';
SET @row2_id = '1111';
SELECT CONCAT(
"SELECT ",
(
SELECT GROUP_CONCAT(" (CASE WHEN t1.", column_name, " != t2.", column_name ," THEN t1.", column_name, " ELSE '-' END) AS ", column_name ,"\n") AS all_column_names
FROM information_schema.columns WHERE table_name = @table_name AND table_schema = DATABASE()
), " FROM ",@table_name," AS t1 INNER JOIN Artiklar AS t2 ON(t1.",@primary_column_name," = '",@row1_id,"' AND t2.",@primary_column_name," = '",@row2_id,"')
UNION ALL
SELECT ",
(
SELECT GROUP_CONCAT(" (CASE WHEN t1.", column_name, " != t2.", column_name ," THEN t2.", column_name, " ELSE '-' END) AS ", column_name ,"\n") AS all_column_names
FROM information_schema.columns WHERE table_name = @table_name AND table_schema = DATABASE()
), " FROM ",@table_name," AS t1 INNER JOIN Artiklar AS t2 ON(t1.",@primary_column_name," = '",@row1_id,"' AND t2.",@primary_column_name," = '",@row2_id,"')
")
It will give you a new SQL query that you can run to see which columns have different values between the two rows.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.