MYSQL具有条件的重复记录计数

时间:2016-01-10 23:57:46

标签: mysql sql

我正在尝试计算重复数据,但我的查询无法正常工作。

每个用户都应该有一个dev_id但是当其他用户拥有相同的dev_id时我想知道这个

表格例如:

 dev_id     user_id
 ------------------
  111           1
  111           1
  222           2
  111           2
  333           3

应该结果:

  user_id       qu
  ------------------
    1           1
    2           1
    3           0

这是我的查询

SELECT t1.user_id,
    (SELECT Count(DISTINCT t2.dev_id)
         FROM reports t2
         WHERE t2.user_id != t1.user_id
         AND t2.dev_id = t1.dev_id
    ) AS qu
FROM       reports t1
GROUP BY   t1.user_id

6 个答案:

答案 0 :(得分:1)

您可以通过以下方式获得结果:

select r.user_id, count(*) - 1
from reports r
group by r.user_id;

这是您想要的计算吗?

答案 1 :(得分:0)

好。让我们从简单开始。

首先,您需要获得唯一的user_id / dev id组合

public class EditFragment extends Fragment {

    private EditCallback editCallback;
    MenuItem save;
    MenuItem cancel;
    View view;
    EditText editText;
    int position;
    Bundle bundle;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        view = inflater.inflate(R.layout.edit_fragment_layout, container, false);
        editText = (EditText) view.findViewById(R.id.editText);
        bundle = getArguments();

        position = bundle.getInt("position");

        editText.setText(bundle.getString("name"));
        return view;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        editCallback = (EditCallback) context;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.edit_fragment, menu);

        save = menu.findItem(R.id.save);
        cancel = menu.findItem(R.id.cancel);

        cancel.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                MyListFragment myListFragment = (MyListFragment) getFragmentManager().findFragmentByTag("MyListFragment");

                fragmentTransaction.replace(R.id.fragContainer, myListFragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
                return true;
            }
        });

        MenuItem menuItem = save.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                if (editCallback != null) {
                    editCallback.updateItem(position, editText.getText().toString());
                    Toast.makeText(getActivity(), "Yor item was updated", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });
    }

    @Override
    public void onDetach() {
        super.onDetach();
        editCallback = null;
    }

    public interface EditCallback {
        void updateItem(int position, String textUpdated);
    }
}

结果将是

select distinct dev_id,user_id from reports

之后,您应该获得每个dev_id

的不同user_id的数量
 dev_id     user_id
 ------------------
  111           1
  222           2
  111           2
  333           3

此类查询的结果将是

select dev_id,c from (
  SELECT
    dev_id,
    count(*)-1 AS c
  FROM
    (select distinct user_id,dev_id from reports) as fixed_reports
  GROUP BY dev_id
                     ) as counts

现在您应该向具有此类dev_id的用户显示。为此你应该加入这样的dev_id列表和step1中的表(显示哪一个user_id,dev_id对存在)

 dev_id     c
 -----------------
  111           1
  222           0
  333           0

"鲜明"这里需要跳过相同的行。

结果应该是内部查询

select distinct fixed_reports2.user_id,counts.c from (
  SELECT
    dev_id,
    count(*)-1 AS c
  FROM
    (select distinct user_id,dev_id from reports) as fixed_reports
  GROUP BY dev_id
                                             ) as counts
      join 
    (select distinct user_id,dev_id from reports) as fixed_reports2
      on fixed_reports2.dev_id=counts.dev_id 
  where counts.c>0 and counts.c is not null

适用于所有查询

 dev_id     c
 -----------------
  111           1

如果您确定还需要c = 0的行,则需要执行" left join"对于fixed_reports2和大型查询,这样你将获得c = null的所有行和行将是0行(可以通过case / when语句更改)

答案 2 :(得分:0)

您的查询已损坏,无法在许多系统上运行。问题是user_id为2的组有两个不同的dev_id。如果您运行下面的“已损坏的查询”,则可以看到min()max()是不同的,但子查询只能看到随机选择的其中一个值。通过将dev_id添加到分组来更正最后一个查询,该分组显示“缺失”行在计数中的位置。

SELECT -- broken query
    t1.user_id, min(t1.dev_id), max(t1.dev_id),
    (select distinct t1.dev_id from reports) as should_have_errored,
    (SELECT Count(DISTINCT t2.dev_id)
         FROM reports t2
         WHERE t2.user_id != t1.user_id
         AND t2.dev_id = t1.dev_id
    ) AS qu
FROM       reports t1
GROUP BY   t1.user_id;

-- On SQL Server that query returns an error 
-- Msg 8120, Level 16, State 1, Line 7
-- Column 'reports.dev_id' is invalid in the select list because it is
-- not contained in either an aggregate function or the GROUP BY clause.

SELECT -- query that duplicates your original query
    t1.user_id,
    (SELECT Count(DISTINCT t2.dev_id)
         FROM reports t2
         WHERE t2.user_id != t1.user_id
         AND t2.dev_id = max(t1.dev_id) /* <-- see here */
    ) AS qu
FROM       reports t1
GROUP BY   t1.user_id;

SELECT t1.user_id, t1.dev_id, -- fixed query
    (SELECT Count(DISTINCT t2.dev_id)
         FROM reports t2
         WHERE t2.user_id != t1.user_id
         AND t2.dev_id = t1.dev_id
    ) AS qu
FROM       reports t1
GROUP BY   t1.user_id, t1.dev_id

http://sqlfiddle.com/#!9/6576e3/20

以下是一些可能有用的查询:

哪个dev_id有多个user_id与之关联?

select dev_id
from reports
group by dev_id
having count(distinct user_id) > 1

哪个user_iddev_id共享user_id

select user_id
from reports r1
where exists (
    select 1
    from reports r2
    where r2.dev_id = r1.dev_id and r2.user_id <> ?
)

或者说这实际上只相当于一个内部联接,这也使得一次列出所有人变得容易。请注意,每对将列出两次:

select r1.user_id, r1.dev_id, r2.user_id as common_user_id
from
    reports r1 inner join reports r2
        on r2.dev_id = r1.dev_id
where
    r1.user_id <> r2.user_id
order by
    r1.user_id, r1.dev_id, r2.user_id

由于您的表格中有重复的行,因此您需要将其设为select distinct才能获得唯一的行。

答案 3 :(得分:0)

我认为以下sql查询应该可以解决你的问题:

SELECT t1.user_id, t1.dev_id, count(t2.user_id) as qu
FROM (Select Distinct * from reports) t1
Left Join (Select Distinct * from reports)  t2
on t1.user_id != t2.user_id and t2.dev_id = t1.dev_id
group by t1.user_Id, t1.dev_id

SQL Fiddle Link

答案 4 :(得分:0)

SELECT user_id, (COUNT(user_id) -1) as qu
FROM reports
GROUP BY user_id

这样可以在您的情况下获得理想的结果,但是您可以更好地改进它。 干杯,,

答案 5 :(得分:-1)

尝试

SELECT 
    user_id, 
    SUM(qu) AS qu
FROM (
    SELECT
        user_id,
        count(*)-1 AS qu
    FROM
        reports
    GROUP BY user_id, dev_id
) AS r
GROUP BY user_id

如果您需要的所有数据都在一个表中,则无需进行连接。

编辑:将组更改为dev_id而不是user_id

Edit2:我认为你需要在group by子句中同时使用dev_id和user_id。

Edit3:添加了一个子查询以获得所需的结果。这可能有点麻烦,也许有人有办法改善这个?