MySQL ВЫБЕРИТЕ IFNULL, затем сравните его численно с другим столбцом - PullRequest
0 голосов
/ 17 февраля 2020

Я пробовал многочисленные методы для перевода NULL в число 0 при выборе:

SELECT
  ss.id AS staff_id,
  u.realname AS realname,
  ss.amount AS salary_amount,
  IF(s.paid_amount IS NOT NULL, s.paid_amount,0.00) AS paid_amount,
  (ss.amount-s.paid_amount)
FROM f_salary_staff ss
  JOIN user u ON (u.id=ss.user_id)
  LEFT JOIN (
    SELECT staff_id,
      month_year,
      SUM(amount) AS paid_amount
    FROM f_salary
    WHERE month_year='2020-02-29'
    GROUP BY staff_id,month_year
  ) s ON (ss.id=s.staff_id)

Я использовал IFNULL, но это вовсе не превращает 0 в любое число c выбор даже не перечислил те со значениями NULL. Есть ли способ вообще преобразовать значения NULL в числовые при выделении и сравнить их численно с другими столбцами?

Кстати ... ниже приведены операторы создания таблиц для обеих таблиц.

f_salary_staff

CREATE TABLE `f_salary_staff` (  `id` int(11) NOT NULL AUTO_INCREMENT, `store_id` int(11) NOT NULL,  `user_id` int(11) NOT NULL,  `date_enter` date DEFAULT NULL,  `amount` decimal(12,2) DEFAULT NULL,  `updated` datetime DEFAULT NULL,  `updated_by` int(11) DEFAULT NULL,  `created` datetime DEFAULT NULL,  `created_by` int(11) DEFAULT NULL,  `last_activated` datetime DEFAULT NULL,  `last_inactivated` datetime DEFAULT NULL,  `status` varchar(16) DEFAULT NULL,  PRIMARY KEY (`id`), KEY `store_id` (`store_id`),  KEY `user_id` (`user_id`),  CONSTRAINT `f_salary_staff_ibfk_1` FOREIGN KEY (`store_id`) REFERENCES `store` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,  CONSTRAINT `f_salary_staff_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE )

затем f_salary

CREATE TABLE `f_salary` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `staff_id` int(11) NOT NULL,  `amount` decimal(12,2) DEFAULT NULL,  `note` tinytext,  `ref_date` date DEFAULT NULL,  `month_year` date DEFAULT NULL,  `created` datetime DEFAULT NULL,  `created_by` int(11) DEFAULT NULL,  `updated` datetime DEFAULT NULL,  `updated_by` int(11) DEFAULT NULL,  `approved` datetime DEFAULT NULL,  `approved_by` int(11) DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `staff_id` (`staff_id`),  CONSTRAINT `f_salary_ibfk_1` FOREIGN KEY (`staff_id`) REFERENCES `f_salary_staff` (`id`) ON DELETE CASCADE ON UPDATE CASCADE )

надеюсь, это поможет тем, кому необходимо понять структуру таблицы

Ответы [ 3 ]

0 голосов
/ 17 февраля 2020

Если я хорошо понимаю ваши потребности, следующий запрос должен работать:

SELECT t.*
FROM (
  SELECT 
    ss.id AS staff_id, 
    u.realname AS realname, 
    ss.amount AS salary_amount, 
    COALESCE(s.paid_amount, 0) AS paid_amount 
  FROM f_salary_staff ss 
  INNER JOIN user u ON (u.id=ss.user_id) 
  LEFT JOIN (
    SELECT staff_id, ref_date, SUM(amount) AS paid_amount 
    FROM f_salary 
    WHERE month_year='2020-02-29' 
    GROUP BY staff_id, ref_date
  ) s ON (ss.id=s.staff_id) 
) t
WHERE paid_amount > salary_amount
0 голосов
/ 17 февраля 2020

Спасибо forpas и Gosfly .. очевидно COALESCE или IFNULL или даже IF не может изменить NULL на что-либо другое, кроме NULL или не NOT NULL ... результат только для показа, но не для его реального значения .. так Я изменил утверждение на такое вместо

SELECT
  ss.id AS staff_id,
  u.realname AS realname,
  ss.amount AS salary_amount,
  IFNULL(s.paid_amount,0.00) AS paid_amount,
  IF(s.paid_amount IS NULL,ss.amount,ss.amount-s.paid_amount) AS unpaid_amount
FROM f_salary_staff ss
  JOIN user u ON (u.id=ss.user_id)
  LEFT JOIN (
    SELECT staff_id,
      month_year,
      SUM(amount) AS paid_amount
    FROM f_salary
    WHERE month_year='2020-02-29'
    GROUP BY staff_id,month_year
  ) s ON (ss.id=s.staff_id)  
WHERE ss.amount != s.paid_amount OR s.paid_amount IS NULL

спасибо всем!

0 голосов
/ 17 февраля 2020

выборка даже не перечисляла те со значениями NULL

, потому что у вас есть LEFT JOIN, который превращается в INNER JOIN с помощью предложения WHERE. Переместите условие в предложение ON. Также в левом соединенном запросе вы выбираете столбец staff_id, хотя он не включен в предложение GROUP BY, как и должно быть. Изменить на это:

SELECT ss.id AS staff_id, u.realname AS realname, ss.amount AS salary_amount, 
COALESCE(s.paid_amount, 0) AS paid_amount,
ss.amount - COALESCE(s.paid_amount, 0)
FROM f_salary_staff ss 
INNER JOIN user u ON (u.id=ss.user_id) 
LEFT JOIN (
  SELECT staff_id, ref_date, SUM(amount) AS paid_amount 
  FROM f_salary 
  WHERE month_year='2020-02-29' 
  GROUP BY staff_id, ref_date
) s ON (ss.id=s.staff_id) AND s.paid_amount > ss.amount
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...