programing

SQL: *condition*이 다른 행에 있는 경우 행을 업데이트합니다.

itsource 2022. 10. 5. 23:27
반응형

SQL: *condition*이 다른 행에 있는 경우 행을 업데이트합니다.

SQL에 문제가 있습니다.

다른 행의 값이 조건에 일치하는 경우에만 지정된 행의 값을 업데이트하고 두 번째 행의 다른 값을 업데이트합니다.

이런 식으로 설명하면 명확하지 않습니다.그래서 코드를 다음에 나타냅니다(mysqli를 사용하여 파라미터를 바인드합니다).

--mariaDB:

UPDATE `accountlist` JOIN `data` ON `accountlist`.`id`=`data`.`id`
    SET `upvotes`= `upvotes` + (`user`= ?),
        `allow` = (CASE WHEN `accountlist`.`id` = ?
                   THEN ?
                   ELSE `allow`
                   END)
WHERE (SELECT `allow` FROM `data` WHERE `id` = ?) < ?;

--mysql:

UPDATE `accountlist` JOIN `data` ON `accountlist`.`id`=`data`.`id`
    SET `upvotes`= `upvotes` + (`user`= ?),
        `allow` = (CASE WHEN `accountlist`.`id` = ?
                   THEN ?
                   ELSE `allow`
                   END)
WHERE `data`.`id` = ? AND `allow` < ?;

--params sample: "admin", 2, "2020-04-20", 2, "2020-04-20"
--               (same value here means always same value)

로컬 호스트와 호스트의 데이터베이스가 다르고 첫 번째 버전이 MySQL에서 작동하지 않기 때문에 MySQL 버전과 MySQL 이외의 버전을 모두 유지해야 합니다.

data1대 1의 관계를 갖는 또 다른 표입니다.accountlist(이것들은 항상 같은 수의 행을 가지고 있으며,ids)

어쨌든, 내가 전화를 걸게user=? 1 및 행:accountlist.id=? 모든 것을 단순화할 수 있습니다.

내가 하고 싶은 일은:

  1. 갱신하다user만약의 경우 1열 1에allow2행의 값은?
  2. 갱신하다allow2행(의 경우allow2행의 값은?)

두 번째 포인트의 조건은 별로 중요하지 않습니다.그것은 그 자체로 갱신되기 때문입니다.

문제:

  • 첫 번째 코드 조각(MySQL 이외) 업데이트upvotes 1에 있지만 변경되지 않음allow번째 줄에 있습니다.
  • 두 번째 코드 조각(MySQL) 업데이트arrow2에 있지만 변경되지 않음user행 1에 있습니다.

고유한 MySQL + 비 MySQL 버전을 의미하는 솔루션이 있습니까?



갱신:

다음은 예를 제시하겠습니다.

     accountlist                       data
   |------------|---------------|    |------------|--------------|----------|
   | id         | user          |    | id         | allow        | upvotes  |
   |------------|---------------|    |------------|--------------|----------|
A: | 1          | admin         |    | 1          | 2020-04-18   | 2        |
B: | 2          | foo           |    | 2          | 2020-04-20   | 0        |
C: | 3          | bar           |    | 3          | 2020-04-22   | 1        |
   |------------|---------------|    |------------|--------------|----------|

파라미터: "admin", "2", "180-04-20", "280-04-20"allowB행은 보다 작지 않다.2020-04-20:

  • 아무 일도 일어나지 않는다.

파라미터: 'admin', 2, 'params-04-22', 2, 'params-04-22'allowB행은 보다 낮다.2020-04-20:

  • upvotesA행의 증가(2->3)
  • allow갱신되었습니다(2020-04-20->2020-04-22)

파라미터: '바', 1, '180-04-19', 1, '180-04-19'allowA행은 보다 낮다2020-04-19:

  • upvotesC행의 값이 증가합니다(1->2)
  • allowA행은 갱신됩니다(2020-04-18->2020-04-19)


업데이트 2:

원하는 작업: 사용자 1이 사용자 2를 업투표하고 싶은 경우(누구나 하루에 한 번이라도 다른 사람을 업투표할 수 있음), 버튼을 클릭했을 때allowed(행의)는 다음 과 비교됩니다.

  • 한다면allowed다음 과 같기 때문에, 유저 1은 이미 다른 유저(유저 2, 유저 3 또는 다른 유저)를 업 투표하고 있기 때문에, 아무것도 변경되지 않습니다.
  • 한다면allowed다음 보다 낮다는 것은 사용자 1이 누군가를 업 투표할 수 있다는 것을 의미합니다.upvote사용자 2의 이 증가하여allow사용자 1의 행은 다음 날로 갱신됩니다.

"사용자 1 또는 사용자 2가 실제로 존재하지 않는 경우" 또는 "사용자 1이 자신을 업투표하려고 하면?"에 대해 걱정하지 마십시오.* PHP 코드로 확인했기 때문입니다.

좀 더 자세히 살펴봅시다.먼저 각 열의 수식을 실시하여 각 열이 어떤 표에 있는지 확인합니다.

UPDATE a JOIN d ON a.`id` = d.`id`
    SET d.`upvotes`= d.`upvotes` + (a.`user`= ?),
        d.`allow` = (CASE WHEN a.`id` = ?
                   THEN ?
                   ELSE d.`allow`
                   END)
WHERE d.`id` = ? AND d.`allow` < ?;

이 두요.id같은 테이블이라고 합시다(1:1은 보통 좋은 스키마 설계가 아닙니다).

UPDATE ad
    SET `upvotes`= `upvotes` + (`user`= ?),
        `allow` = (CASE WHEN `id` = ?
                   THEN ?
                   ELSE `allow`
                   END)
WHERE `id` = ? AND `allow` < ?;

이제 알 수 있듯이CASE낭비되고 있습니다. 이 는 '간단히 하다'로 단순화 됩니다.

UPDATE ad
    SET `upvotes`= `upvotes` + (`user`= ?),
        `allow` = ?
WHERE `id` = ? AND `allow` < ?;

이제 2개의 테이블로 돌아가 보겠습니다.

UPDATE a JOIN d ON a.`id` = d.`id`
    SET d.upvotes = d.upvotes + (a.user = ?),
        d.allow = ?
    WHERE d.id = ? AND d.allow < ?;

다른 형태로 이어지죠. (이게 더 나은지 아닌지 모르겠네요)

UPDATE d
    SET d.upvotes = d.upvotes +
                    ( ( SELECT  user = ? FROM a WHERE a.id = d.id ) )
        d.allow = ?
    WHERE d.id = ? AND d.allow < ?;

또는 (또한 유의한 차이가 없을 수 있음)

UPDATE d
    SET d.upvotes = d.upvotes +
                EXISTS ( SELECT  user = ? FROM a WHERE a.id = d.id )
        d.allow = ?
    WHERE d.id = ? AND d.allow < ?;

고객님의 문제에 대한 해결책을 찾으려고 노력했습니다.아마도 제가 올바르게 이해하고 있는 답변 ID가 여기 있습니다.wor flow : 각 사용자는 하루에 1번씩 업베이트 할 수 있습니다.

  1. user1 user2 업투표
  2. 이 오늘이미 ?user1은 업보트를 했습니까?
    도 하지 마세요.->아무것도 하지 마세요.
    : 및 >no : user1의

그 예: "admin", "2", "120-04-20", "120-04-20"

  • 2 = > 사용자 1
  • admin = > user2
  • "194-04-20" => 업투표일

맞습니까?그렇다면 이쪽이 해결책입니다.

마리애드

UPDATE data SET upvotes = CASE WHEN id = (SELECT id FROM accountlist WHERE accountlist.user = ?)
                AND 
               (SELECT allow FROM data inner join accountlist on accountlist.id = data.id 
                 where accountlist.id = ? )< ?
            THEN upvotes + 1
            ELSE upvotes
          END,
allow = CASE WHEN id = ?
THEN ?
ELSE allow
END

mysql

UPDATE data
SET upvotes = CASE WHEN id = (SELECT id FROM (select * from accountlist) as al WHERE al.user = "bar")
                    AND 
                   (SELECT allow FROM (select * from data) as d inner join (select * from accountlist) as al1 on al1.id = d.id where al1.id = 1)<"2020-04-19"
                THEN upvotes + 1
                ELSE upvotes
              END,
allow = CASE WHEN id = 1
THEN "2020-04-19"
ELSE allow
END;

작성된 데이터베이스:

         accountlist                       data
   |------------|---------------|    |------------|--------------|----------|
   | id         | user          |    | id         | allow        | upvotes  |
   |------------|---------------|    |------------|--------------|----------|
A: | 1          | admin         |    | 1          | 2020-04-18   | 2        |
B: | 2          | foo           |    | 2          | 2020-04-20   | 0        |
C: | 3          | bar           |    | 3          | 2020-04-22   | 1        |
   |------------|---------------|    |------------|--------------|----------|

값: "admin", "2", "control-04-20", "2", "control-04-20" => 변경 없음

'admin', '2', '128-04-22', '2', '128-04-22'

         accountlist                       data
   |------------|---------------|    |------------|--------------|----------|
   | id         | user          |    | id         | allow        | upvotes  |
   |------------|---------------|    |------------|--------------|----------|
A: | 1          | admin         |    | 1          | 2020-04-18   | 3        |
B: | 2          | foo           |    | 2          | 2020-04-22   | 0        |
C: | 3          | bar           |    | 3          | 2020-04-22   | 1        |
   |------------|---------------|    |------------|--------------|----------|

"bar", 1, "bar-04-19", 1, "bar-04-19" =>

             accountlist                       data
   |------------|---------------|    |------------|--------------|----------|
   | id         | user          |    | id         | allow        | upvotes  |
   |------------|---------------|    |------------|--------------|----------|
A: | 1          | admin         |    | 1          | 2020-04-19   | 3        |
B: | 2          | foo           |    | 2          | 2020-04-22   | 0        |
C: | 3          | bar           |    | 3          | 2020-04-22   | 2        |
   |------------|---------------|    |------------|--------------|----------|

정상적으로 동작하고 있는 것(온라인에서 동작하고 있는 것)이지만, 1이 아닌 2개의 스테이트먼트를 사용하는 것이 간단합니다.

언급URL : https://stackoverflow.com/questions/61326558/sql-update-a-row-if-condition-on-another-row

반응형