-2

代替テキスト

特定の名前について、この人が住んでいた 3 つ以上の都市に住んでいた他の名前を取得したいと考えています。

4

9 に答える 9

12

これはあなたがすべきことです:

都市テーブルを持つようにデータベースを再設計します。

city(id int, name varchar)

およびユーザーテーブル:

user(id int, name varchar, ...)

および user_city テーブル:

user_city(user_id int, city_id int)

それだけで、ユーザーごとに 10 都市という制限がなくなります。

ユーザーが住んでいる都市を見つけるには:

select city_id form user_city where user_id = ?

そのリストから 3 つ以上の都市に住んでいるユーザーを見つけるにはどうすればよいでしょうか。これを行う 1 つの方法は、次のように、各ユーザーが住んでいたリストから都市の数を数えることです。

select user_id,count(*) n 
from user_city 
where city_id in (select city_id 
                  from user_city 
                  where user_id = ?) 
group by user_id having n >= 3;

私はこれを実際にテストしませんでしたが、うまくいくはずです。

また、それらのテーブルにインデックスを付ける方法を理解する必要があります。

于 2010-03-18T09:05:33.223 に答える
4

binomial(10,3)^2クエリを実行するには OR 条件が必要です。それは 14 400 です。あなたはそれをしたくありません。

于 2010-03-18T12:32:09.437 に答える
2

代わりにテーブルを再設計する必要があります

名前 , 都市 1 , 都市 2 , 都市 3 , 都市 4 , 都市 5 , 都市 6 , 都市 7 , 都市 8 , 都市 9 都市 10

それはもっと似ているはずです

Person, City, rank
------------------
name , city1 ,1
name , city2 ,2 
name , city3 ,3 
name , city4 ,4 
name , city5 ,5 
name , city6 ,6 
name , city7 ,7 
name , city8 ,8 
name , city9 ,9 
name , city10,10

TomTom のアドバイスを受けて、データの正規化について学びましょう!

于 2010-03-18T08:57:48.627 に答える
2

データベースを再設計しないというあなたの要求を尊重します

まだ試していない私のアイデア、今すぐテストする方法はありません

ユニオンなどでビュー(名前、都市)を作成しselect name, c1ますselect name, c2...

それで:

select m2.name from myview m1
inner join myview m2 on m1.city = m2.city
where m1.name = @Name AND m2.Name!=@Name
group by m2.name
having count(m2.name) > 2 
于 2010-03-18T12:33:13.087 に答える
1

うん。

テーブルをデザインする方法を学ぶために、コメントを付けてテーブルをデザインした人にテーブルを送り返します。第一正規形、正規化。

テーブルがSQLルールに従うと、クエリは非常に簡単になります。

于 2010-03-18T08:53:50.257 に答える
1

次のようなことを試してください:

SELECT PersonName,COUNT(*) AS CountOf
    FROM (SELECT PersonName,city1 FROM PersonCities WHERE city1 IS NOT NULL
          UNION SELECT PersonName,city2 FROM PersonCities WHERE city2 IS NOT NULL
          UNION SELECT PersonName,city3 FROM PersonCities WHERE city3 IS NOT NULL
          UNION SELECT PersonName,city4 FROM PersonCities WHERE city4 IS NOT NULL
          UNION SELECT PersonName,city5 FROM PersonCities WHERE city5 IS NOT NULL
          ...
         ) dt
    WHERE dt.city1 IN (SELECT city1 FROM PersonCities WHERE PersonName=..SearchPerson.. AND city1 IS NOT NULL
                       UNION SELECT city2 FROM PersonCities WHERE PersonName=..SearchPerson.. AND city2 IS NOT NULL
                       UNION SELECT city3 FROM PersonCities WHERE PersonName=..SearchPerson.. AND city3 IS NOT NULL
                       UNION SELECT city4 FROM PersonCities WHERE PersonName=..SearchPerson.. AND city4 IS NOT NULL
                       UNION SELECT city5 FROM PersonCities WHERE PersonName=..SearchPerson.. AND city5 IS NOT NULL
                       ...
                       )
        AND PersonName!=@SearchPerson
    GROUP BY PersonName
    HAVING COUNT(*)>=3

私は mysql を持っていないので、ここでは SQL Server を使用して実行しています。

DECLARE @PersonCities table(PersonName varchar(10), city1 varchar(10), city2 varchar(10), city3 varchar(10), city4 varchar(10), city5 varchar(10))
INSERT INTO @PersonCities VALUES ('Joe','AAA','BBB','CCC', NULL, NULL)
INSERT INTO @PersonCities VALUES ('Pat','BBB','DDD','EEE','FFF','GGG')
INSERT INTO @PersonCities VALUES ('Sam','FFF','BBB', NULL, NULL, NULL)
INSERT INTO @PersonCities VALUES ('Ron','HHH','DDD','EEE','FFF', NULL)
INSERT INTO @PersonCities VALUES ('Don','FFF','ZZZ','QQQ', NULL, NULL)

DECLARE @SearchPerson varchar(10)
SET @SearchPerson='Pat'

SELECT PersonName,COUNT(*) AS CountOf
    FROM (SELECT PersonName,city1 FROM @PersonCities WHERE city1 IS NOT NULL
          UNION SELECT PersonName,city2 FROM @PersonCities WHERE city2 IS NOT NULL
          UNION SELECT PersonName,city3 FROM @PersonCities WHERE city3 IS NOT NULL
          UNION SELECT PersonName,city4 FROM @PersonCities WHERE city4 IS NOT NULL
          UNION SELECT PersonName,city5 FROM @PersonCities WHERE city5 IS NOT NULL
         ) dt
    WHERE dt.city1 IN (SELECT city1 FROM @PersonCities WHERE PersonName=@SearchPerson AND city1 IS NOT NULL
                       UNION SELECT city2 FROM @PersonCities WHERE PersonName=@SearchPerson AND city2 IS NOT NULL
                       UNION SELECT city3 FROM @PersonCities WHERE PersonName=@SearchPerson AND city3 IS NOT NULL
                       UNION SELECT city4 FROM @PersonCities WHERE PersonName=@SearchPerson AND city4 IS NOT NULL
                       UNION SELECT city5 FROM @PersonCities WHERE PersonName=@SearchPerson AND city5 IS NOT NULL
                       )
        AND PersonName!=@SearchPerson
    GROUP BY PersonName
    HAVING COUNT(*)>=3

出力:

PersonName 
---------- -----------
Ron        3

(1 row(s) affected)
于 2010-03-18T12:56:31.747 に答える
0

これを試して:

<テーブル>Person
<フィールド>PersonId、PersonName |

<テーブル>都市
<フィールド>CityId、CityName |

<テーブル>LivedIn
<フィールド>LivedInId、PersonId、CityId

論理的には、シナリオごとに次のことを行います。

  1. さまざまな都市の最大数に住んでいる人を見つける:
    PersonId(すべての人)のリストを作成します
    それを繰り返し、各人が住んでいた都市の数を数えます人が住んで
    いる最大の都市
    を見つけます人の名前を見つけます最大の都市を持っていたpersonIdに関連する

  2. 3つ以上の都市に住んでいたすべての人をギブパーソンとして検索する人を
    ボブと呼びましょう
    ボブが住んでいたすべての都市(CityIds)
    のリストを作成します。personIdと一般的な都市(JavaのHashMapなど)を含むリストを作成します。 )
    LivedInテーブルを反復処理し、一般的な都市の数を更新します。数
    が3を超えるすべての人を検索します。

私はJavaとSQLの組み合わせでこれを行いますが、どちらもあまり得意ではないので、多くのことを調べなくてもここでコードを提供することはできません。

于 2010-03-18T09:11:50.700 に答える
0

データベースを正規化する必要があります。

そうすることで、列を取得できます

名前、都市(オプションでCityOrder)。

その後、これらの結果を必要なものに組み合わせる方法を見つける必要があります。これを行うには、Join、Count、Groupbyを理解する必要があります。

于 2010-03-18T08:56:19.177 に答える
0

このデータを 3 つのテーブルに分割して、より柔軟な多対多の関係を提供します。

person名前を格納するテーブル2 つを関連付ける
city都市を格納するテーブル(多対多)
person_city

navin が持っている 3 つ以上の都市に住んでいた他の人を取得するには:

SELECT name FROM (
    SELECT
        p.name, COUNT(DISTINCT(city_id)) AS lived
    FROM person p 
    JOIN person_city pc ON (pc.person_id = p.person_id) 
    JOIN city c ON (c.city_id = pc.city_id) 
    WHERE city_id IN (
        SELECT c2.city_id 
        FROM city c2 
        JOIN person_city pc2 ON (c2.city_id = pc2.city_id) 
        JOIN person p2 ON (p2.person_id = pc2.person_id) 
        WHERE p2.name = 'navin' 
    )
    GROUP BY person_id HAVING lived >= 3
) AS multihome 
WHERE name <> 'navin';
于 2010-03-18T12:18:53.450 に答える