Query only displaying one result - php

I have the following query that all along I thought my while loop was not working, but it turns out my query is only outputting one record.
SELECT up.ordering, u.id, u.username, up.playername
FROM users AS u
INNER JOIN playersByUser AS up ON u.id = up.userid
WHERE u.group IN (3,4,5)
ORDER BY up.ordering
It should be outputting several and I am unsure why it is only getting one. I'm trying to select the id's from both the users and playersByUser table where the group is 5 in the users table. Then output the username.
playersByUser
CREATE TABLE `playersByUser` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) DEFAULT NULL,
`playername` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`ordering` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `userid` (`userid`),
CONSTRAINT `playersByUser_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
users
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`lastname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`phone_number` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`username` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`salt` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`joined` datetime NOT NULL,
`group` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_c
The data that can be used is this:
users
id firstname lastname email phone_number username password salt joined group
1 name1 lastname1 email#email.com 555-555-5555 testSQL fdfdf acc 9-3-15 5
2 name2 lastname2 email2#email.com 555-555-5556 testSQL2 fdfdf dcc 9-3-15 5
playersByUser
id userid playername ordering
1 1 Bob 1
2 2 Dave 1

Have you tried renaming your users.group field? also have you tried a left join in case data doesn't exist on your joined table?
SELECT playersByUser.ordering, users.id, users.username, playersByUser.playername
FROM users, playersByUser where users.id = playersByUser.userid
AND `users.group` IN (3,4,5)
ORDER BY playersByUser.ordering
works fine for me in phpMyAdmin

Related

SQL JOIN replacing an unwanted column

I created a JOIN query to be able to access the username column from the users table where t.user_id = u.id.
Unfortunately, there is an issue since creating this query. Now when I try to use the id from the triggers table, my variable is picking up the id from the users table.
Does anyone see how I can fix this?
try {
$con = getConfig('pdo');
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql_triggers = "
SELECT
t.*,
u.id,
u.username
FROM
triggers AS t
LEFT JOIN
users AS u ON t.user_id = u.id
";
$triggers_stmt = $con->prepare($sql_triggers);
$triggers_stmt->execute();
$triggers_rows = $triggers_stmt->fetchAll(PDO::FETCH_ASSOC);
$triggers_arr = array();
foreach ($triggers_rows as $triggers_row) {
$trigger_id = $triggers_row['id'];
$trigger_title = $triggers_row['trigger_name'];
$trigger_description = $triggers_row['description'];
$trigger_setting = $triggers_row['setting'];
$trigger_user = $triggers_row['user_id'];
$trigger_username = $triggers_row['username'];
triggers = t
CREATE TABLE `triggers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`trigger_name` varchar(70) COLLATE utf8_unicode_ci NOT NULL,
`setting` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`description` text COLLATE utf8_unicode_ci NOT NULL,
`user_id` int(11) NOT NULL,
`placement` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`date_changed` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
users = u
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(55) COLLATE utf8_unicode_ci NOT NULL,
`lastname` varchar(55) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(55) COLLATE utf8_unicode_ci NOT NULL,
`username` varchar(70) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`salt` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`joined` datetime NOT NULL,
`last_login` datetime NOT NULL,
`group` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_c
I was able to modify the SQL to get the result I was looking for. The users id column was clashing with the triggers id column. As NigelRen pointed out, changing u.id, to u.id AS uid, solved this issue.
SELECT
t.*,
u.id AS uid,
u.username
FROM
triggers AS t
LEFT JOIN
users AS u ON t.user_id = u.id
";

Multiple joins producing unwanted results

I'm getting weird results from my query. The numbers are way off and I can't figure out why.
Heres the table structure for the tables used in the query:
CREATE TABLE IF NOT EXISTS `bookings` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`customer_id` int(11) DEFAULT NULL,
`payment_method_id` int(11) DEFAULT NULL,
`date` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`time` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`details` text COLLATE utf8mb4_unicode_ci,
`ip` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`status` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'Complete',
`booked_at` timestamp NULL DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `booking_products` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`booking_id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`amount` int(11) NOT NULL,
`price_subtotal` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`price_total` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `booking_services` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`booking_id` int(11) NOT NULL,
`service_id` int(11) NOT NULL,
`reservations` int(11) NOT NULL,
`price_subtotal` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`price_total` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `payment_methods` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `payment_methods_name_unique` (`name`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Here is my query:
return DB::table('bookings')
->selectRaw('payment_methods.name, count(bookings.id) as bookings, (sum(booking_services.price_subtotal) + sum(booking_products.price_subtotal)) as subtotal')
->join('booking_services', 'booking_services.booking_id', '=', 'bookings.id')
->join('booking_products', 'booking_products.booking_id', '=', 'bookings.id')
->join('payment_methods', 'payment_methods.id', '=', 'bookings.payment_method_id')
->where('bookings.status', 'Complete')
->whereBetween('bookings.booked_at', [$this->carbon_from, $this->carbon_to])
->groupBy('payment_methods.id')
->orderBy('payment_methods.name')
->get();
$this->carbon_from and $this->carbon_to are carbon objects which work fine.
I'm trying to obtain the total bookings and a sum of the price_subtotals for each payment method. It seems to be grouping the booking products/services together rather than by each payment method like I want.
Am I missing something here?
Edit: here is the query log:
select payment_methods.name,
count(bookings.id) as bookings,
(sum(booking_services.price_subtotal) + sum(booking_products.price_subtotal)) as subtotal
from `bookings`
inner join `booking_services` on `booking_services`.`booking_id` = `bookings`.`id`
inner join `booking_products` on `booking_products`.`booking_id` = `bookings`.`id`
inner join `payment_methods` on `payment_methods`.`id` = `bookings`.`payment_method_id`
where `bookings`.`status` = ? and `bookings`.`booked_at` between ? and ?
group by `payment_methods`.`id`
order by `payment_methods`.`name` asc
I guess you are getting cross product that is why you are getting wrong numbers for aggregation, what i suggest you, calculate your sum in individual sub clauses and then join these clauses with your main query like
SELECT p.name,
COUNT(DISTINCT b.id) AS bookings,
bs.price_subtotal + bp.price_subtotal AS subtotal
FROM bookings b
INNER JOIN (
SELECT booking_id, SUM(price_subtotal) price_subtotal
FROM booking_services
GROUP BY booking_id
) bs ON b.id = bs.booking_id
INNER JOIN (
SELECT booking_id, SUM(price_subtotal) price_subtotal
FROM booking_products
GROUP BY booking_id
) bp ON b.id = bp.booking_id
INNER JOIN payment_methods p ON p.id = b.payment_method_id
WHERE b.status = ?
AND b.booked_at BETWEEN ? AND ?
GROUP BY p.name
ORDER BY p.name
I have no clue how to transform/write above query using laravel's query builder/eloquent way
Try to group by payment_method_id from the bookings table:
->groupBy('bookings.payment_method_id')

MYSQL query to find duplicate records based on first name and last name

I have a user table with following columns and i have come up with a query to identify the duplicate records based on the first name and last name.
table structure
CREATE TABLE IF NOT EXISTS `User` (
`id` bigint(20) NOT NULL,
`address1` text COLLATE utf8_unicode_ci,
`mobile` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`firstName` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`lastName` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`username` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
`password` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`email` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`gender` tinyint(2) NOT NULL DEFAULT '0' COMMENT '1 - female, 2-male, 0 - unknown',
`zip` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`countryCode` varchar(3) COLLATE utf8_unicode_ci DEFAULT NULL,
`joinedDate` datetime DEFAULT NULL,
`dateOfBirth` date DEFAULT NULL COMMENT 'User date of birth'
) ENGINE=MyISAM AUTO_INCREMENT=63561 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
and my query
SELECT id, firstName, lastName, mobile, email, count(*) as dupCount
FROM `User` `t`
WHERE firstName is not null and lastName is not null
GROUP BY firstName,lastName HAVING count(*) > 1
ORDER BY t.joinedDate DESC
below is the screenshot of the result when i run the query
and my data set is here http://pastebin.com/Y5qsTcFc
sorry if paste bin is not working. try this https://drive.google.com/file/d/0B3gG6MG9uh7KdmRGT3d0NWg2aVk/view?usp=sharing
when there are records with email address is NULL, we have a problem. i am always getting this error.
1062 - Duplicate entry 'Rachel-Besnainou' for key 'group_key'
Query i ran is:
SELECT id, firstName, lastName, mobile, email, count(*) as dupCount
FROM `User` `t`
WHERE firstName is not null and lastName is not null
GROUP BY firstName,lastName
HAVING count(*) > 1
I have no idea why this error comes up. any help appreciated
Update 1
i try to add this to my database and ran the query still it was the same
SET SESSION max_heap_table_size=536870912;
SET SESSION tmp_table_size=536870912;
ref: Duplicate entry for key 'group_key'
Update 2
I tried the same database in diff mysql and phpmyadmin version and it worked. so looks like my mysql version has a bug. my mysql version is 5.6.26
Try this:
select a1.id,
a1.FirstName,
a1.LastName,
a1.mobile,
a1.email
from user a1
inner join
(
select FirstName, LastName, count(id)
from User
where firstname is not null
and lastname is not null
group by FirstName, LastName
having count(id)>1
) u1
on u1.FirstName = a1.Firstname
and u1.Lastname = a1.lastname
order by a1.joineddate

Selecting rows that corresponds from other table

I have a product table that stores all products. Also I have a production table that stores productions.
I am using CodeIgniter and datamapper ORM.
Here is tables:
CREATE TABLE IF NOT EXISTS `products` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`kod_stok` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`kod_lokal` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
`kod_firma` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`firma` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`fabrika` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`proje` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`tanim` mediumtext COLLATE utf8_unicode_ci,
`saatlik_uretim` int(11) NOT NULL,
`status` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `kod_lokal` (`kod_lokal`),
KEY `kod_firma` (`kod_firma`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
CREATE TABLE IF NOT EXISTS `productions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fabrika` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`board_no` int(11) NOT NULL,
`date` int(11) DEFAULT NULL, // Unix Timestamp
`operator_id` int(11) DEFAULT NULL,
`product_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `product` (`product_id`),
KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
I am trying to get count of production of given day. But not all products, producting everyday. I need to exlude the products that has 0 count.
$p = new Product();
$p->include_related_count('production');
$p->get();
And I want to add a date interval to production.
Basicly, I want to get all product's production count within a given day.
How can I do that?
Thank you for any advices.
Not sure about codeigniter details, but the following SQL query will generate a production list per day.
To get today's production:
$query = $this->db->query("
SELECT
a.count(*) as produced
, a.product_id
, b.kod_stok as productname
FROM productions a
INNER JOIN products b ON (a.product_id = b.id)
WHERE FROM_UNIXTIME(a.date) = CURDATE()
GROUP BY TO_DAYS(FROM_UNIXTIME(a.date)), a.product_id
");
To get last 7 days production
$query = $this->db->query("
SELECT
a.count(*) as produced
, a.product_id
, b.kod_stok as productname
FROM productions a
INNER JOIN products b ON (a.product_id = b.id)
WHERE FROM_UNIXTIME(a.date)
BETWEEN DATE_SUB(CURDATE(),INTERVAL 7 DAY) AND CURDATE()
GROUP BY TO_DAYS(FROM_UNIXTIME(a.date)), a.product_id
");

Unable to relate two MySQL tables (foreign keys)

Here is my USER table
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL,
`expiry` varchar(6) NOT NULL,
`contact_id` int(11) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(100) NOT NULL,
`level` int(3) NOT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
And here is my contact_info table
CREATE TABLE IF NOT EXISTS `contact_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`email_address` varchar(255) NOT NULL,
`company_name` varchar(255) NOT NULL,
`license_number` varchar(255) NOT NULL,
`phone` varchar(30) NOT NULL,
`fax` varchar(30) NOT NULL,
`mobile` varchar(30) NOT NULL,
`category` varchar(100) NOT NULL,
`country` varchar(20) NOT NULL,
`state` varchar(20) NOT NULL,
`city` varchar(100) NOT NULL,
`postcode` varchar(50) NOT NULL,
PRIMARY KEY (`id`,`email_address`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
The system uses username to login users. I want to modify it in such a way that it uses email for login. But there is no email_address in users table.
I have added foreign key - email in user table(which is email_address in contact_info).
How should I query database?
No, no, no, no no. Seriously, no. Don't make me come over there :-)
You're breaking third normal form by storing the email address twice.
The relationship need only be a short one, that of id. Assuming you're not guaranteeing the IDs will be identical in the two tables (i.e., my users.id isn't necessarily equal to my contact_info.id), just add a ci_id to the users table to act as a foreign key to the contact_info table.
Then the query to get a user's username and email will be something like:
select u.username, ci.email
from users u, contact_info ci
where u.username = 'paxdiablo'
and u.ci_id = ci.id;

Categories