这个查询行吗? MySql与左联接和嵌套查询一对多

时间:2020-09-28 18:14:27

标签: mysql mariadb left-join sql-order-by greatest-n-per-group

花了一段时间找到最好的理由后,我以这个查询结束了,我只是想知道它是否按预期工作?经验表明,MySQL总是给我一个惊喜。我的查询在结构上是错误的,或者没有达到预期的效率。

这是查询:

laravel/ui

用户表:

select
      `users`.*,
      `i`.`name` as `identity_name`,
      `i`.`id` as `identity_id`,
      `i`.`is_verified`
    from
      `users`
      left join `identities` as `i` on `i`.`user_id` = `users`.`id`
      and `i`.`id` = (
        select
          `i2`.`id`
        from
          `identities` as `i2`
        where
          `i2`.`user_id` = `i`.`user_id`
        order by
          `i2`.`is_verified` desc,
          `i2`.`updated_at` desc
        limit
          1
      )

身份表:

+---+-------------------+
| id| other columns ... |
+---+-------------------+
| 1 | user data ...     |
| 2 | user data ...     |
| 3 | user data ...     |
| 4 | user data ...     |
|...| user data ...     |
+---+-------------------+

预期输出:对于每个用户,应该从身份表中获得一个身份。 is_verified = 1,然后更新的update_at的身份具有更高的优先级

很明显,id = 1的用户是有问题的。

1 个答案:

答案 0 :(得分:1)

如果您的MySql / Mariadb版本支持窗口函数,则可以使用 command: 'c:\users\hp\pycharmprojects\myworkprojects\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\hp\\AppData\\ Local\\Temp\\pip-install-tcpoer0q\\pycryptodome\\setup.py'"'"'; __file__='"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-tcpoer0q\\pycryptodome\\setup.py'"'"'; f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdis t_wheel -d 'C:\Users\hp\AppData\Local\Temp\pip-wheel-2tffvi57' cwd: C:\Users\hp\AppData\Local\Temp\pip-install-tcpoer0q\pycryptodome\ Complete output (364 lines): running bdist_wheel running build running build_py creating build creating build\lib.win-amd64-3.8 creating build\lib.win-amd64-3.8\Crypto copying lib\Crypto\__init__.py -> build\lib.win-amd64-3.8\Crypto creating build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\AES.py -> build\lib.win-amd64-3.8\Crypto\Cipher ---------------------------------------- ERROR: Failed building wheel for pycryptodome Running setup.py clean for pycryptodome Failed to build pycryptodome Installing collected packages: pycryptodome, Pyrebase Running setup.py install for pycryptodome ... error ERROR: Command errored out with exit status 1: command: 'c:\users\hp\pycharmprojects\myworkprojects\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\hp\\AppData \\Local\\Temp\\pip-install-tcpoer0q\\pycryptodome\\setup.py'"'"'; __file__='"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-tcpoer0q\\pycryptodome\\setup.py'"'" ';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' in stall --record 'C:\Users\hp\AppData\Local\Temp\pip-record-dxesdn53\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\hp\p ycharmprojects\myworkprojects\venv\include\site\python3.8\pycryptodome' cwd: C:\Users\hp\AppData\Local\Temp\pip-install-tcpoer0q\pycryptodome\ Complete output (363 lines): running install running build running build_py creating build\lib.win-amd64-3.8 creating build\lib.win-amd64-3.8\Crypto copying lib\Crypto\__init__.py -> build\lib.win-amd64-3.8\Crypto creating build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\AES.py -> build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\ARC2.py -> build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\ARC4.py -> build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\Blowfish.py -> build\lib.win-amd64-3.8\Crypto\Cipher ---------------------------------------- ERROR: Command errored out with exit status 1: 'c:\users\hp\pycharmprojects\myworkprojects\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv [0] = '"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-tcpoer0q\\pycryptodome\\setup.py'"'"'; __file__='"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-tcp oer0q\\pycryptodome\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(cod e, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\hp\AppData\Local\Temp\pip-record-dxesdn53\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\hp\pycharmprojects\myworkprojects\venv\include\site\python3.8\pycryptodome' Check the logs for full command output. (venv) C:\Users\hp\PycharmProjects\MyWorkProjects>pip install Pyrebase Collecting Pyrebase Using cached Pyrebase-3.0.27-py3-none-any.whl (9.6 kB) Requirement already satisfied: requests-toolbelt==0.7.0 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from Pyrebase) (0.7.0) Requirement already satisfied: gcloud==0.17.0 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from Pyrebase) (0.17.0) Collecting pycryptodome==3.4.3 Using cached pycryptodome-3.4.3.tar.gz (6.5 MB) Requirement already satisfied: requests==2.11.1 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from Pyrebase) (2.11.1) Requirement already satisfied: oauth2client==3.0.0 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from Pyrebase) (3.0.0) Requirement already satisfied: python-jwt==2.0.1 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from Pyrebase) (2.0.1) Requirement already satisfied: httplib2>=0.9.1 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from gcloud==0.17.0->Pyrebase) (0.18.1) Requirement already satisfied: googleapis-common-protos in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from gcloud==0.17.0->Pyrebase) (1.52.0) Requirement already satisfied: protobuf!=3.0.0.b2.post1,>=3.0.0b2 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from gcloud==0.17.0->Pyrebase ) (3.13.0) Requirement already satisfied: six in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from gcloud==0.17.0->Pyrebase) (1.15.0) Requirement already satisfied: pyasn1>=0.1.7 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from oauth2client==3.0.0->Pyrebase) (0.4.8) Requirement already satisfied: pyasn1-modules>=0.0.5 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from oauth2client==3.0.0->Pyrebase) (0.2.8 ) Requirement already satisfied: rsa>=3.1.4 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from oauth2client==3.0.0->Pyrebase) (4.6) Requirement already satisfied: jws>=0.1.3 in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from python-jwt==2.0.1->Pyrebase) (0.1.3) Requirement already satisfied: setuptools in c:\users\hp\pycharmprojects\myworkprojects\venv\lib\site-packages (from protobuf!=3.0.0.b2.post1,>=3.0.0b2->gcloud==0.17 .0->Pyrebase) (50.3.0) Building wheels for collected packages: pycryptodome Building wheel for pycryptodome (setup.py) ... error ERROR: Command errored out with exit status 1: command: 'c:\users\hp\pycharmprojects\myworkprojects\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\hp\\AppData\\ Local\\Temp\\pip-install-h4tye5vg\\pycryptodome\\setup.py'"'"'; __file__='"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-h4tye5vg\\pycryptodome\\setup.py'"'"'; f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdis t_wheel -d 'C:\Users\hp\AppData\Local\Temp\pip-wheel-n2zgp_ai' cwd: C:\Users\hp\AppData\Local\Temp\pip-install-h4tye5vg\pycryptodome\ Complete output (364 lines): running bdist_wheel running build running build_py creating build creating build\lib.win-amd64-3.8 creating build\lib.win-amd64-3.8\Crypto copying lib\Crypto\__init__.py -> build\lib.win-amd64-3.8\Crypto creating build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\AES.py -> build\lib.win-amd64-3.8\Crypto\Cipher copying lib\Crypto\Cipher\ARC2.py -> build\lib.win-amd64-3.8\Crypto\Cipher ERROR: Command errored out with exit status 1: 'c:\users\hp\pycharmprojects\myworkprojects\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv [0] = '"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-h4tye5vg\\pycryptodome\\setup.py'"'"'; __file__='"'"'C:\\Users\\hp\\AppData\\Local\\Temp\\pip-install-h4t ye5vg\\pycryptodome\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(cod e, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\hp\AppData\Local\Temp\pip-record-_4my5q46\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\hp\pycharmprojects\myworkprojects\venv\include\site\python3.8\pycryptodome' Check the logs for full command output.

ROW_NUMBER()

请参见demo
结果:

select u.*, i.name as identity_name, i.id as identity_id, i.is_verified
from users u 
left join (
  select *, 
    row_number() over (partition by user_id order by is_verified desc, updated_at desc) rn 
  from identities
) as i on i.user_id = u.id and i.rn = 1