Есть ли способ отобразить записи INNER JOIN в том порядке, в котором они введены в предложении? - PullRequest
0 голосов
/ 29 апреля 2019

Я начинающий, когда дело доходит до MySQL, и я взял на себя задачу создать такой тип переводческого сервиса, как google translate. Проблема в том, что запросы не отображаются так, как я их ввожу, вместо этого они, похоже, упорядочены по столбцу идентификаторов.

Я пытался (с моими ограниченными знаниями) изучить различные способы создания отношений и т. Д., Чтобы отобразить одинаковые слова на разных языках. Сейчас я попытался использовать предложение INNER JOIN для отображения и «структурирования» предложений.

SELECT swedish.word,
       german.word,
       german.swear,
       swedish.swear,
       swedish.id
FROM   swedish
       INNER JOIN german
               ON swedish.id = german.id
WHERE  swedish.word = "Hej"
        OR swedish.word = "Mitt"
        OR swedish.word = "Namn"
        OR swedish.word = "Är"; 

Это будет отображать шведские слова вместе с немецкими словами, то есть создавать предложения, но теперь оно будет отображаться в том порядке, в котором я их набрал, вместо этого он будет сортироваться по столбцу ID, который смешивает слова вокруг. Есть ли какое-то решение для этого?

Вот и изображение результатов, упорядоченных по ID:

enter image description here

Я думал об использовании ORDER BY и некотором временном значении, а затем упорядочил его по этому, но тогда я не уверен, как реализовать и автоматически увеличить это значение только для выбранных записей / строк.

Я использую операторы OR, чтобы включить более одной записи в одном и том же результате, так как скобки (в других руководствах) приводили к синтаксическим ошибкам.

Кроме того, если есть лучший способ сделать это, пожалуйста, дайте мне знать!

РЕДАКТИРОВАТЬ: Я хотел бы уточнить, что я знаю, что это не является устойчивым решением для создания службы Transaltion, я просто подумал, что это будет интересный способ понять немного больше о том, как вы можете подключиться и работать с различными столы и т. д.

Ответы [ 7 ]

1 голос
/ 29 апреля 2019

Я бы предложил подзапрос с расстановкой приоритетов:

SELECT s.word, g.word, g.swear, s.swear, s.id
FROM swedish s JOIN
     (SELECT 'Hej' as word, 1 as ord UNION ALL
      SELECT 'Mitt' as word, 2 as ord UNION ALL
      SELECT 'Namn' as word, 3 as ord UNION ALL
      SELECT 'Är' as word, 4 as ord
     ) w
     ON s.word = w.word JOIN
     german g
     ON s.id = g.id
ORDER BY w.ord;

Преимущество этого подхода перед другими подходами состоит в том, что список слов включается только один раз. Это упрощает обновление и предотвращает ошибки при написании запроса.

1 голос
/ 29 апреля 2019

Кроме того, если есть лучший способ сделать это, пожалуйста, дайте мне знать!

Это не работа с базами данных, а работа переднего конца

Если у вас есть предложение;

Хей Митт Намн Ар Кай

Тогда передний конец должен сделать что-то вроде этого (псевдокод):

string newsentence = “”
foreach(word in sentence.split(‘ ‘))
  newsentence = newsentence + “ “ + dblookup(word)

(Можно предположить, что dblookup - это вспомогательный метод, который принимает одно [шведское] слово и возвращает эквивалентное одиночное [немецкое] слово)

Порядок сохраняется, поскольку вы выполняете поиск в базе данных в порядкеВы пересекаете предложение.Вы не пытаетесь отправить все слова в БД и принудительно упорядочиваете результаты, чтобы вы могли просто объединить их обратно в предложение, вы просматриваете одно слово за раз.Если в предложении дважды содержится одно и то же слово, все подходы здесь (в других ответах - на момент написания этого ответа) будут нарушены;предложение «хей митт хей» будет возвращено в порядке «алло хэлло мейн», потому что вы не можете попросить БД назначить хей первым и третьим, все «хей» прикажут быть первыми

Не много чего можно получить, отправив несколько слов для перевода, может быть, небольшое преимущество в производительности, но это будет тривиально.Если бы вы разрабатывали это решение для повышения производительности, вы могли бы иметь в своем методе dblookup кэш нескольких сотен тысяч самых последних запрошенных слов, но не стучите головой о попытке отправить целое предложение в БД в «или или или»стиль и сохранение порядка;это так сложно сделать без какой-либо практической пользы

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

1 голос
/ 29 апреля 2019

Вы можете использовать FIND_IN_SET

ORDER BY FIND_IN_SET(swedish.word, 'Hej,Mitt,Namn,Är');
0 голосов
/ 29 апреля 2019

Тот же ответ, что и у Гордона Линоффа, просто автоматизирует нумерацию порядка списка фильтров:

CREATE TABLE tbl
    (fruit varchar(10), sweetness int)
;

INSERT INTO tbl
    (fruit, sweetness)
VALUES
    ('apple', 7),
    ('banana', 6),
    ('papaya', 4),
    ('grape', 2),
    ('watermelon', 3)
;

Запрос, включая Postgres для его выразительности:)

Живой тест: http://sqlfiddle.com/#!17/3fa48/3

with a as
(
   select * 
   from unnest(array['banana','grape','apple','banana']) 
   with ordinality as x(f,i)
)
select tbl.*,'',a.i 
from tbl
join a on tbl.fruit = a.f
order by a.i;

Вывод:

|  fruit | sweetness | ?column? | i |
|--------|-----------|----------|---|
| banana |         6 |          | 1 |
|  grape |         2 |          | 2 |
|  apple |         7 |          | 3 |
| banana |         6 |          | 4 |

Запрос для MySQL:

Тест в реальном времени: http://sqlfiddle.com/#!9/86b0d9/4

select tbl.*, '', a.i 
from tbl
join (
    select @i := @i + 1 as i, x.f
    from
    (
      select 'banana' as f
      union all
      select 'grape'
      union all
      select 'apple'
      union all
      select 'banana'
    ) as x
    cross join (select @i := 0) y    
) a on tbl.fruit = a.f
order by a.i;

Вывод:

|  fruit | sweetness |  | i |
|--------|-----------|--|---|
| banana |         6 |  | 1 |
|  grape |         2 |  | 2 |
|  apple |         7 |  | 3 |
| banana |         6 |  | 4 |        
0 голосов
/ 29 апреля 2019

Существуют некоторые фундаментальные проблемы с вашим вопросом:

Я взял на себя задачу создать такой переводческий сервис, как google translate.

Автоматический перевод сложный и не может быть решен с помощью простого поиска в базе данных (особенно, если вы "новичок, когда дело доходит до MySQL").Языки имеют много сложных правил грамматики, и вы не можете перевести предложение, просто переводя его в слово в слово.Взгляните на эту статью : вам действительно нужно заняться чем-то вроде машинного обучения, а не (просто) разработкой базы данных.

Если вам нужен опыт автоматического перевода, вы можете взглянуть на Google Translate API .

Другая проблема заключается в том, что у вас, кажется, есть отдельная таблица / сущность для каждого языка.Это проблематично: по мере роста количества языков количество таблиц будет увеличиваться.Чтобы перевести с Language A на Language B, вам нужно знать, какие таблицы использовать, что, вероятно, будет включать динамический SQL.Было бы гораздо лучше правильно нормализовать ваши данные.Примерно так:

CREATE TABLE Words
(
    word_id INT PRIMARY KEY, 
    universal_name VARCHAR(255) -- the "universal" way to refer to a word (e.g. you could store the Esperanto version).
);

INSERT INTO Words
(word_id, universal_name) 
VALUES 
(1, 'hello');

CREATE TABLE word_translations
(
    word_id INT NOT NULL FOREIGN KEY REFERENCES Words(word_id), 
    language VARCHAR(255) NOT NULL, 
    word_name VARCHAR(255) NOT NULL
);

INSERT INTO word_translations
(word_id, language, word_name)
VALUES
(1, 'en', 'hello'),
(1, 'es', 'hola');

Но, опять же, это не решит проблему перевода, так как дословных переводов недостаточно.

0 голосов
/ 29 апреля 2019

Не уверен, что вы это имеете в виду, но попробуйте так:

   SELECT swedish.word,
           german.word,
           german.swear,
           swedish.swear,
           swedish.id
    FROM   swedish
           INNER JOIN german
                   ON swedish.id = german.id
    WHERE  swedish.word = "Hej"
            OR swedish.word = "Mitt"
            OR swedish.word = "Namn"
            OR swedish.word = "Är"
    ORDER BY field(swedish.word,"Hej","Mitt","Namn","Är");
0 голосов
/ 29 апреля 2019

Вы можете предоставить способ сортировки строк с помощью CASE в ORDER BY:

SELECT 
  swedish.word, german.word, german.swear, swedish.swear, swedish.id 
FROM swedish INNER JOIN german 
ON swedish.id = german.id 
WHERE swedish.word IN ('Hej', 'Mitt', 'Namn', 'Är')
ORDER BY CASE swedish.word
  WHEN 'Hej' THEN 1
  WHEN 'Mitt' THEN 2
  WHEN 'Namn' THEN 3
  WHEN 'Är' THEN 4
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...